{"id":39433902,"url":"https://github.com/arunabhverma/expo-paste-input","last_synced_at":"2026-04-02T17:02:50.061Z","repository":{"id":328515726,"uuid":"1103580361","full_name":"arunabhverma/expo-paste-input","owner":"arunabhverma","description":"Cross-platform native paste handling for React Native.","archived":false,"fork":false,"pushed_at":"2026-03-28T20:29:37.000Z","size":11024,"stargazers_count":247,"open_issues_count":1,"forks_count":6,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-28T22:26:31.394Z","etag":null,"topics":["on-paste-event","onpaste","paste-input","react-native","react-native-image-paste-input","react-native-paste-input","text-input"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/expo-paste-input","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arunabhverma.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-25T04:03:05.000Z","updated_at":"2026-03-28T20:29:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/arunabhverma/expo-paste-input","commit_stats":null,"previous_names":["arunabhverma/expo-paste-input"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/arunabhverma/expo-paste-input","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arunabhverma%2Fexpo-paste-input","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arunabhverma%2Fexpo-paste-input/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arunabhverma%2Fexpo-paste-input/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arunabhverma%2Fexpo-paste-input/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arunabhverma","download_url":"https://codeload.github.com/arunabhverma/expo-paste-input/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arunabhverma%2Fexpo-paste-input/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31311018,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T12:59:32.332Z","status":"ssl_error","status_checked_at":"2026-04-02T12:54:48.875Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["on-paste-event","onpaste","paste-input","react-native","react-native-image-paste-input","react-native-paste-input","text-input"],"created_at":"2026-01-18T04:09:01.379Z","updated_at":"2026-04-02T17:02:50.056Z","avatar_url":"https://github.com/arunabhverma.png","language":"Swift","funding_links":[],"categories":["Swift"],"sub_categories":[],"readme":"# expo-paste-input\n\n`expo-paste-input` is a lightweight wrapper around React Native `TextInput` that lets users paste images and GIFs directly from the system clipboard on **iOS and Android**.\n\nIt works at the native level to intercept paste events before React Native handles them, giving you access to pasted media as local file URIs while keeping full control over your own `TextInput` component.\n\nSee the original demo on [Twitter](https://x.com/iamarunabh/status/1997738168247062774)\n\n| iOS | Android |\n| --- | --- |\n| \u003cimg src=\"https://github.com/user-attachments/assets/c7d9baac-b2f8-4942-9a7f-52932e65ae7e\" /\u003e | \u003cimg src=\"https://github.com/user-attachments/assets/6057745c-ccfc-4ca0-935d-9aa4668f22e3\" /\u003e |\n\n\n---\n\n## Features\n\n- Paste **text, images, and multiple GIFs**\n- Works on **iOS and Android**\n- True wrapper around `TextInput` (bring your own input)\n- No custom UI, no opinionated styles\n- Returns local file URIs for pasted media\n- Safe to import on Web (no crash, no-op)\n- Supports Expo SwiftUI `TextField` as well.\n\n---\n\n## Installation\n\n### Quick install\n\n```bash\nnpx expo install expo-paste-input\n````\n\nor\n\n```bash\nyarn add expo-paste-input\n```\n\n### Rebuild the app (required)\n\nThis library uses native code, so you must rebuild.\n\n```bash\nnpx expo run:ios\nnpx expo run:android\n```\n\n(Expo Go will not work)\n\n---\n\n## Usage\n\nWrap your `TextInput` with `TextInputWrapper`:\n\n```tsx\nimport { TextInputWrapper } from \"expo-paste-input\";\nimport { TextInput } from \"react-native\";\n\nexport default function MyInput() {\n  return (\n    \u003cTextInputWrapper\n      onPaste={(payload) =\u003e {\n        console.log(payload);\n      }}\n    \u003e\n      \u003cTextInput placeholder=\"Paste here...\" /\u003e\n    \u003c/TextInputWrapper\u003e\n  );\n}\n```\n\n---\n\n## Props\n\n| Prop     | Type                                   | Description                                                                        |\n| -------- | -------------------------------------- | ---------------------------------------------------------------------------------- |\n| children | `React.ReactElement`                   | The `TextInput` (or any custom input) you want to wrap.                            |\n| onPaste  | `(payload: PasteEventPayload) =\u003e void` | Callback fired when a paste event is detected. Receives pasted text or image URIs. |\n\n---\n\n## Types\n\n```ts\ntype PasteEventPayload =\n  | { type: \"text\"; value: string }\n  | { type: \"images\"; uris: string[] }\n  | { type: \"unsupported\" };\n```\n\n* `text` → pasted text\n* `images` → local file URIs (`file://...`)\n* `unsupported` → anything else\n\n---\n\n## Why a wrapper?\n\nThis library does **not** reimplement `TextInput`.\n\nInstead:\n\n```tsx\n\u003cTextInputWrapper\u003e\n  \u003cTextInput /\u003e\n\u003c/TextInputWrapper\u003e\n```\n\nThis means:\n\n* you keep full control of your input\n* works with any custom TextInput\n* no prop mirroring\n* future-proof with RN updates\n\n---\n\n## Platform behavior\n\n### iOS\n\n* Intercepts native `paste(_:)`\n* Extracts images from `UIPasteboard`\n* Saves to temp files\n* Preserves GIFs\n\n### Android\n\n* Uses `OnReceiveContentListener` + `ActionMode`\n* Prevents Android \"Can't paste images\" toast\n* Saves pasted media to cache\n\n---\n\n## Notes\n\n* Image URIs are temporary files, move them if you need persistence.\n* Text paste events fire after the text is inserted.\n* Image paste events prevent default paste (since TextInput can't render images).\n* Web is currently a no-op implementation.\n\n---\n\n## Inspiration\n\nInspired by work from:\n\n- **Fernando Rojo** — [native paste handling in the v0 app](https://x.com/fernandorojo/status/1993098916456452464)\n\n- **v0.dev** — real-world product pushing React Native closer to native UX\n\n---\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farunabhverma%2Fexpo-paste-input","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farunabhverma%2Fexpo-paste-input","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farunabhverma%2Fexpo-paste-input/lists"}