react-smart-paste 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 react-smart-paste contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,207 @@
1
- # Temporary Holding Version
1
+ # react-smart-paste
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Paste any text and let AI fill your form. A React button and hook that read the form, send the pasted text to your model, show the proposed values, and fill the fields once the user approves. MIT licensed.
4
+
5
+ **[Live demo](https://saravanananbu.github.io/react-smart-paste/)** · [npm](https://www.npmjs.com/package/react-smart-paste)
6
+
7
+ - Works on plain HTML forms: no schema to declare, it reads names, labels, types and options from the page
8
+ - Review before anything changes, per-field tick boxes, and undo
9
+ - Never overwrites what the user already typed (unless you ask it to)
10
+ - Passwords, payment fields, files and hidden inputs are never read, sent or filled
11
+ - Any model: you pass one function that calls your backend, so no API key reaches the browser
12
+ - Fills React-controlled and uncontrolled inputs alike, by setting values the way typing does
13
+ - Falls back to a paste box when the browser blocks clipboard access
14
+ - Ships with `"use client"`, ESM and CommonJS builds, and TypeScript types
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ npm install react-smart-paste
20
+ ```
21
+
22
+ `react` and `react-dom` (18 or newer) are peer dependencies.
23
+
24
+ ## Usage
25
+
26
+ Put the button inside your form and give it a `complete` function that calls your backend:
27
+
28
+ ```tsx
29
+ import { SmartPasteButton, type SmartPasteComplete } from "react-smart-paste";
30
+ import "react-smart-paste/styles.css";
31
+
32
+ const complete: SmartPasteComplete = ({ text, fields, signal }) =>
33
+ fetch("/api/smart-paste", { method: "POST", body: JSON.stringify({ text, fields }), signal });
34
+
35
+ export function ContactForm() {
36
+ return (
37
+ <form>
38
+ <label>
39
+ Name <input name="name" />
40
+ </label>
41
+ <label>
42
+ Email <input name="email" type="email" />
43
+ </label>
44
+ <label>
45
+ Country
46
+ <select name="country">
47
+ <option value="">Choose…</option>
48
+ <option value="in">India</option>
49
+ <option value="us">United States</option>
50
+ </select>
51
+ </label>
52
+
53
+ <SmartPasteButton complete={complete} />
54
+ </form>
55
+ );
56
+ }
57
+ ```
58
+
59
+ The user copies some text (an email signature, an invoice, a message), presses **Smart paste**, checks the list of proposed values, and presses **Fill all**.
60
+
61
+ Every control needs a `name`. Good labels give better results: the model sees each field's label, type, options, placeholder and `autocomplete` hint.
62
+
63
+ ## The backend route
64
+
65
+ `react-smart-paste/server` exports the prompt builder with no React code, so it is safe to import on a server. Send its `system` and `user` messages to any model and return the model's text.
66
+
67
+ ```ts
68
+ // app/api/smart-paste/route.ts (Next.js). Set ANTHROPIC_API_KEY in .env.local
69
+ import Anthropic from "@anthropic-ai/sdk";
70
+ import { buildSmartPastePrompt } from "react-smart-paste/server";
71
+
72
+ const client = new Anthropic(); // reads ANTHROPIC_API_KEY on the server
73
+
74
+ export async function POST(req: Request) {
75
+ const { text, fields } = await req.json();
76
+ if (typeof text !== "string" || text.length > 20000 || !Array.isArray(fields)) {
77
+ return new Response("Bad request", { status: 400 });
78
+ }
79
+
80
+ const { system, user } = buildSmartPastePrompt({ text, fields });
81
+ const message = await client.messages.create({
82
+ model: "claude-opus-5-5",
83
+ max_tokens: 2048,
84
+ system,
85
+ messages: [{ role: "user", content: user }],
86
+ });
87
+
88
+ const reply = message.content.map((block) => (block.type === "text" ? block.text : "")).join("");
89
+ return new Response(reply);
90
+ }
91
+ ```
92
+
93
+ The same shape works with OpenAI, Gemini or a local model: pass `system` and `user`, return the text.
94
+
95
+ - Keep the API key in a server-only env variable. Variables named `VITE_*` or `NEXT_PUBLIC_*` are copied into the browser bundle and are not secret.
96
+ - A route like this lets anyone who can reach it spend your AI budget. Put it behind your app's sign-in and add a rate limit.
97
+
98
+ `complete` may return a `Response`, the model's text as a string, or an object of field values you parsed yourself.
99
+
100
+ ## Button props
101
+
102
+ | Prop | Type | Default | Description |
103
+ | --- | --- | --- | --- |
104
+ | `complete` | `(request) => Response \| string \| object` | required | Sends `{ text, fields, signal }` to your model. |
105
+ | `form` | `RefObject<HTMLFormElement>` | the enclosing `<form>` | The form to fill, when the button sits outside it. |
106
+ | `overwrite` | `"empty" \| "all"` | `"empty"` | `"empty"` fills blank fields only. `"all"` may replace existing values. |
107
+ | `review` | `boolean` | `true` | Show the proposed values for approval. `false` fills straight away. |
108
+ | `maxLength` | `number` | `20000` | Longest pasted text that will be sent, in characters. |
109
+ | `children` | `ReactNode` | `"Smart paste"` | Button text. |
110
+ | `theme` | `"light" \| "dark" \| "auto"` | `"auto"` | `"auto"` follows the OS setting. |
111
+ | `align` | `"start" \| "end"` | `"start"` | Which side of the button the panel lines up with. |
112
+ | `disabled`, `className` | – | – | Passed to the button / wrapper. |
113
+ | `onApply` | `(changes) => void` | – | Called after fields are filled. |
114
+ | `onError` | `(error) => void` | – | Called when a paste fails. |
115
+
116
+ ## The hook
117
+
118
+ For your own button and review UI, use `useSmartPaste`:
119
+
120
+ ```tsx
121
+ import { useRef } from "react";
122
+ import { useSmartPaste } from "react-smart-paste";
123
+
124
+ function ContactForm() {
125
+ const form = useRef<HTMLFormElement>(null);
126
+ const smart = useSmartPaste({ form, complete });
127
+
128
+ return (
129
+ <form ref={form}>
130
+ <input name="email" type="email" />
131
+
132
+ <button type="button" onClick={() => smart.paste()}>
133
+ Paste
134
+ </button>
135
+
136
+ {smart.status === "review" && (
137
+ <div>
138
+ {smart.changes.map((change) => (
139
+ <p key={change.name}>
140
+ {change.label}: {change.to}
141
+ </p>
142
+ ))}
143
+ <button type="button" onClick={() => smart.accept()}>Fill</button>
144
+ <button type="button" onClick={smart.discard}>Discard</button>
145
+ </div>
146
+ )}
147
+ {smart.status === "error" && <p role="alert">{smart.error?.message}</p>}
148
+ </form>
149
+ );
150
+ }
151
+ ```
152
+
153
+ | Returned | Description |
154
+ | --- | --- |
155
+ | `status` | `"idle"`, `"working"`, `"review"`, `"applied"`, `"nothing"` (no match) or `"error"`. |
156
+ | `changes` | In `review`, the proposed edits; in `applied`, the edits made. Each has `name`, `label`, `from`, `to`, `value`. |
157
+ | `error` | A `SmartPasteError` with a `code`: `clipboard`, `empty`, `too-long`, `no-form`, `no-fields`, `request` or `response`. |
158
+ | `paste(text?)` | Fill from `text`, or from the clipboard when called with no argument. |
159
+ | `accept(names?)` | Apply the reviewed changes, or only the named fields. |
160
+ | `discard()` / `cancel()` | Drop the proposal, or stop a request in progress. |
161
+ | `undo()` / `canUndo` | Put back the values the last fill replaced. |
162
+
163
+ The hook takes the same `complete`, `overwrite`, `review`, `maxLength`, `onApply` and `onError` options as the button. `form` is a ref or a function returning the form element.
164
+
165
+ Reading the clipboard needs a user gesture and permission, and some browsers refuse it. When that happens `error.code` is `"clipboard"`: show a text box and call `paste(text)` with what the user pastes into it. The button does this for you.
166
+
167
+ ## What is read and what is not
168
+
169
+ Fields are found through the form's controls. These are always left out, so they are never described to the model and never filled:
170
+
171
+ - `password`, `file` and `hidden` inputs, and buttons
172
+ - fields whose `autocomplete` is a payment token (`cc-number`, `cc-csc`, …), `current-password`, `new-password` or `one-time-code`
173
+ - disabled and read-only controls
174
+ - anything inside an element with `data-smart-paste="off"`
175
+
176
+ With the default `overwrite="empty"`, fields that already have a value are left out too. The current values of fields are never sent, only their descriptions.
177
+
178
+ ## Safety and privacy
179
+
180
+ - **The pasted text goes to your model.** Tell your users, as you would for any AI feature. Nothing is sent until they press the button.
181
+ - **The model's answer is validated before it is shown.** Only known field names are accepted, and each value must fit its field: a real date, a listed option, a well-formed email, an `http(s)` URL. Anything else is dropped. Values are set as plain form values, never as HTML.
182
+ - **Pasted text is treated as data.** The prompt tells the model not to follow instructions inside it, and the validation above limits what a manipulated answer could do to choosing wrong values for visible fields, which the user reviews before filling.
183
+
184
+ ## Theming
185
+
186
+ Override any `--rsp-*` variable on `.rsp`:
187
+
188
+ ```css
189
+ .rsp {
190
+ --rsp-accent: #7c3aed;
191
+ --rsp-radius: 10px;
192
+ }
193
+ ```
194
+
195
+ Available variables: `bg`, `fg`, `muted`, `border`, `hover`, `accent`, `on-accent`, `danger`, `radius`, `shadow`, `font`.
196
+
197
+ ## Lower-level helpers
198
+
199
+ `readFields(form)`, `applyValues(form, values)`, `buildSmartPastePrompt({ text, fields })` and `parseSmartPasteResponse(reply, fields)` are exported for building your own flow.
200
+
201
+ ## Contributing
202
+
203
+ Setup, build and test instructions are in [CONTRIBUTING.md](./CONTRIBUTING.md).
204
+
205
+ ## License
206
+
207
+ [MIT](./LICENSE)