@mattermost/react-native-paste-input
v2.0.1
Published
React Native TextInput replacement to allow pasting files (Fabric only)
Readme
@mattermost/react-native-paste-input
React Native TextInput component has functionality to capture text input from a user
by using the soft and hardware keyboards but lacks the ability to restrict copy & paste options
as well as allowing pasting different file formats copied from other apps, like images & videos from
the Photos gallery app.
PasteInput is a TextInput replacement that solves these issues.
Requirements
- React Native >= 0.76.0 (Fabric/New Architecture only)
- iOS >= 13.4
- Android minSdkVersion >= 21
Installation
npm install --save-exact @mattermost/react-native-paste-inputiOS Setup (Required)
You need to call PasteInputModule.setup from your AppDelegate so the library can locate native views. Choose the snippet that matches your AppDelegate style.
AppDelegate.swift
import UIKit
import React
import React_RCTAppDelegate
import ReactAppDependencyProvider
import react_native_paste_input
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var reactNativeDelegate: ReactNativeDelegate?
var reactNativeFactory: RCTReactNativeFactory?
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
let delegate = ReactNativeDelegate()
let factory = RCTReactNativeFactory(delegate: delegate)
delegate.dependencyProvider = RCTAppDependencyProvider()
reactNativeDelegate = delegate
reactNativeFactory = factory
window = UIWindow(frame: UIScreen.main.bounds)
factory.startReactNative(
withModuleName: "YourAppName",
in: window,
launchOptions: launchOptions
)
PasteInputModule.setup(factory.rootViewFactory)
return true
}
}
class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
override func bundleURL() -> URL? {
#if DEBUG
RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
#else
Bundle.main.url(forResource: "main", withExtension: "jsbundle")
#endif
}
}AppDelegate.mm
// AppDelegate.mm
#import <React/RCTAppDelegate.h>
#import <react_native_paste_input/PasteInputModule.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.moduleName = @"YourAppName";
BOOL result = [super application:application didFinishLaunchingWithOptions:launchOptions];
[PasteInputModule setup:self.rootViewFactory];
return result;
}
@endNote: Without this call the library cannot locate native views by tag and paste events will not be delivered.
Android Setup
No additional setup required - autolinking will handle everything.
Demo
| Android | iOS |
|---------|-----|
|
|
|
Usage
import React, { useRef } from 'react';
import PasteInput, { PastedFile, PasteInputRef } from "@mattermost/react-native-paste-input";
const YourTextInput = () => {
const inputRef = useRef<PasteInputRef>(null);
const onPaste = (
error: string | null | undefined,
files: Array<PastedFile>
) => {
if (error) {
console.error('Paste error:', error);
return;
}
console.log('PASTED FILES', files);
// files is an array of { fileName, fileSize, type, uri }
};
return (
<PasteInput
ref={inputRef}
disableCopyPaste={false}
onPaste={onPaste}
multiline={true}
blurOnSubmit={false}
underlineColorAndroid="transparent"
keyboardType="default"
disableFullscreenUI={true}
textContentType="none"
autoComplete="off"
/>
);
}API
Properties
All properties of the TextInput component plus:
disableCopyPaste: boolean
Indicates if the menu items for cut, copy, paste and share should not be present in the context menu.
Default: false
onPaste: (error: string | null, files: PastedFile[]) => void
Callback that is called when pasting files into the text input.
Note: On Android, this callback is also called when selecting an image/GIF from the soft keyboard.
Parameters:
error: Error message if paste failed, otherwisenullfiles: Array of pasted files
smartPunctuation?: 'default' | 'enable' | 'disable' (iOS only)
Controls iOS smart punctuation behavior.
Default: 'default'
Types
interface PastedFile {
fileName: string;
fileSize: number;
type: string; // MIME type
uri: string; // file:// URI
}
type PasteInputRef = TextInput; // Fully compatible with TextInput refArchitecture
This library uses a hybrid approach to provide paste interception across platforms:
iOS
- Uses a TurboModule with dynamic subclassing (ISA swizzling)
- Wraps standard React Native
TextInput(100% compatible) - Registers the TextInput ref with the native module on mount
- Intercepts paste events at the UIKit level
- Works in both bridgeless and bridge modes
Android
- Uses a custom ComponentView that extends
ReactEditText - Overrides
onCreateInputConnectionto intercept paste viaInputConnectionCompat - Handles clipboard content from various sources (images, files, Google Docs, etc.)
- Fully compatible with TextInput API
Compatibility
| React Native Version | Supported | |---------------------|-----------| | 0.83.x | ✅ | | 0.82.x | ✅ | | 0.81.x | ✅ | | 0.80.x | ✅ | | 0.79.x | ✅ | | 0.78.x | ✅ | | 0.77.x | ✅ | | 0.76.x | ✅ | | < 0.76 | ❌ (Old Architecture not supported) |
Troubleshooting
iOS: Views not being registered
If you see errors about views not being found:
- Ensure you've called
PasteInputModule.setupin your AppDelegate (see iOS Setup above) - Make sure you've run
pod installafter adding the library - Clean build folder and rebuild:
cd ios && rm -rf build && cd .. && npx react-native run-ios
Android: Build errors
If you encounter build errors:
- Clean the build:
cd android && ./gradlew clean && cd .. - Rebuild:
npx react-native run-android
Contributing
See the contributing guide to learn how to contribute to the repository and the development workflow.
License
MIT
