@usefy/use-copy-to-clipboard 0.0.17 → 0.0.18
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/README.md +66 -67
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -83,14 +83,14 @@ This package requires React 18 or 19:
|
|
|
83
83
|
## Quick Start
|
|
84
84
|
|
|
85
85
|
```tsx
|
|
86
|
-
import { useCopyToClipboard } from
|
|
86
|
+
import { useCopyToClipboard } from "@usefy/use-copy-to-clipboard";
|
|
87
87
|
|
|
88
88
|
function CopyButton() {
|
|
89
89
|
const [copiedText, copy] = useCopyToClipboard();
|
|
90
90
|
|
|
91
91
|
return (
|
|
92
|
-
<button onClick={() => copy(
|
|
93
|
-
{copiedText ?
|
|
92
|
+
<button onClick={() => copy("Hello World!")}>
|
|
93
|
+
{copiedText ? "Copied!" : "Copy"}
|
|
94
94
|
</button>
|
|
95
95
|
);
|
|
96
96
|
}
|
|
@@ -106,24 +106,24 @@ A hook that provides clipboard copy functionality with state tracking.
|
|
|
106
106
|
|
|
107
107
|
#### Parameters
|
|
108
108
|
|
|
109
|
-
| Parameter | Type
|
|
110
|
-
|
|
109
|
+
| Parameter | Type | Description |
|
|
110
|
+
| --------- | --------------------------- | --------------------- |
|
|
111
111
|
| `options` | `UseCopyToClipboardOptions` | Configuration options |
|
|
112
112
|
|
|
113
113
|
#### Options
|
|
114
114
|
|
|
115
|
-
| Option
|
|
116
|
-
|
|
117
|
-
| `timeout`
|
|
118
|
-
| `onSuccess` | `(text: string) => void` | —
|
|
119
|
-
| `onError`
|
|
115
|
+
| Option | Type | Default | Description |
|
|
116
|
+
| ----------- | ------------------------ | ------- | --------------------------------------------------------------------- |
|
|
117
|
+
| `timeout` | `number` | `2000` | Time in ms before `copiedText` resets to null. Set to `0` to disable. |
|
|
118
|
+
| `onSuccess` | `(text: string) => void` | — | Callback called when copy succeeds |
|
|
119
|
+
| `onError` | `(error: Error) => void` | — | Callback called when copy fails |
|
|
120
120
|
|
|
121
121
|
#### Returns `[copiedText, copy]`
|
|
122
122
|
|
|
123
|
-
| Index | Type
|
|
124
|
-
|
|
125
|
-
| `[0]` | `string \| null`
|
|
126
|
-
| `[1]` | `(text: string) => Promise<boolean>` | Async function to copy text
|
|
123
|
+
| Index | Type | Description |
|
|
124
|
+
| ----- | ------------------------------------ | -------------------------------------------- |
|
|
125
|
+
| `[0]` | `string \| null` | The last successfully copied text, or `null` |
|
|
126
|
+
| `[1]` | `(text: string) => Promise<boolean>` | Async function to copy text |
|
|
127
127
|
|
|
128
128
|
---
|
|
129
129
|
|
|
@@ -132,14 +132,14 @@ A hook that provides clipboard copy functionality with state tracking.
|
|
|
132
132
|
### Basic Copy Button
|
|
133
133
|
|
|
134
134
|
```tsx
|
|
135
|
-
import { useCopyToClipboard } from
|
|
135
|
+
import { useCopyToClipboard } from "@usefy/use-copy-to-clipboard";
|
|
136
136
|
|
|
137
137
|
function CopyButton({ text }: { text: string }) {
|
|
138
138
|
const [copiedText, copy] = useCopyToClipboard();
|
|
139
139
|
|
|
140
140
|
return (
|
|
141
141
|
<button onClick={() => copy(text)}>
|
|
142
|
-
{copiedText === text ?
|
|
142
|
+
{copiedText === text ? "Copied!" : "Copy to Clipboard"}
|
|
143
143
|
</button>
|
|
144
144
|
);
|
|
145
145
|
}
|
|
@@ -148,23 +148,20 @@ function CopyButton({ text }: { text: string }) {
|
|
|
148
148
|
### Copy with Visual Feedback
|
|
149
149
|
|
|
150
150
|
```tsx
|
|
151
|
-
import { useCopyToClipboard } from
|
|
151
|
+
import { useCopyToClipboard } from "@usefy/use-copy-to-clipboard";
|
|
152
152
|
|
|
153
153
|
function CopyWithIcon({ text }: { text: string }) {
|
|
154
154
|
const [copiedText, copy] = useCopyToClipboard();
|
|
155
155
|
const isCopied = copiedText === text;
|
|
156
156
|
|
|
157
157
|
return (
|
|
158
|
-
<button
|
|
159
|
-
onClick={() => copy(text)}
|
|
160
|
-
className={isCopied ? 'copied' : ''}
|
|
161
|
-
>
|
|
158
|
+
<button onClick={() => copy(text)} className={isCopied ? "copied" : ""}>
|
|
162
159
|
{isCopied ? (
|
|
163
160
|
<CheckIcon className="icon" />
|
|
164
161
|
) : (
|
|
165
162
|
<CopyIcon className="icon" />
|
|
166
163
|
)}
|
|
167
|
-
{isCopied ?
|
|
164
|
+
{isCopied ? "Copied!" : "Copy"}
|
|
168
165
|
</button>
|
|
169
166
|
);
|
|
170
167
|
}
|
|
@@ -173,7 +170,7 @@ function CopyWithIcon({ text }: { text: string }) {
|
|
|
173
170
|
### Code Block with Copy
|
|
174
171
|
|
|
175
172
|
```tsx
|
|
176
|
-
import { useCopyToClipboard } from
|
|
173
|
+
import { useCopyToClipboard } from "@usefy/use-copy-to-clipboard";
|
|
177
174
|
|
|
178
175
|
function CodeBlock({ code, language }: { code: string; language: string }) {
|
|
179
176
|
const [copiedText, copy] = useCopyToClipboard();
|
|
@@ -183,7 +180,7 @@ function CodeBlock({ code, language }: { code: string; language: string }) {
|
|
|
183
180
|
<div className="code-header">
|
|
184
181
|
<span>{language}</span>
|
|
185
182
|
<button onClick={() => copy(code)}>
|
|
186
|
-
{copiedText === code ?
|
|
183
|
+
{copiedText === code ? "Copied!" : "Copy Code"}
|
|
187
184
|
</button>
|
|
188
185
|
</div>
|
|
189
186
|
<pre>
|
|
@@ -197,15 +194,15 @@ function CodeBlock({ code, language }: { code: string; language: string }) {
|
|
|
197
194
|
### Custom Timeout
|
|
198
195
|
|
|
199
196
|
```tsx
|
|
200
|
-
import { useCopyToClipboard } from
|
|
197
|
+
import { useCopyToClipboard } from "@usefy/use-copy-to-clipboard";
|
|
201
198
|
|
|
202
199
|
function LongFeedbackCopy() {
|
|
203
200
|
// Show "Copied!" for 5 seconds
|
|
204
201
|
const [copiedText, copy] = useCopyToClipboard({ timeout: 5000 });
|
|
205
202
|
|
|
206
203
|
return (
|
|
207
|
-
<button onClick={() => copy(
|
|
208
|
-
{copiedText ?
|
|
204
|
+
<button onClick={() => copy("Long feedback!")}>
|
|
205
|
+
{copiedText ? "Copied!" : "Copy"}
|
|
209
206
|
</button>
|
|
210
207
|
);
|
|
211
208
|
}
|
|
@@ -214,7 +211,7 @@ function LongFeedbackCopy() {
|
|
|
214
211
|
### Persistent Copied State
|
|
215
212
|
|
|
216
213
|
```tsx
|
|
217
|
-
import { useCopyToClipboard } from
|
|
214
|
+
import { useCopyToClipboard } from "@usefy/use-copy-to-clipboard";
|
|
218
215
|
|
|
219
216
|
function PersistentCopy() {
|
|
220
217
|
// Never auto-reset the copied state
|
|
@@ -222,8 +219,8 @@ function PersistentCopy() {
|
|
|
222
219
|
|
|
223
220
|
return (
|
|
224
221
|
<div>
|
|
225
|
-
<button onClick={() => copy(
|
|
226
|
-
{copiedText ?
|
|
222
|
+
<button onClick={() => copy("Persistent!")}>
|
|
223
|
+
{copiedText ? "Copied!" : "Copy"}
|
|
227
224
|
</button>
|
|
228
225
|
{copiedText && <span>Copied text: {copiedText}</span>}
|
|
229
226
|
</div>
|
|
@@ -234,8 +231,8 @@ function PersistentCopy() {
|
|
|
234
231
|
### With Callbacks
|
|
235
232
|
|
|
236
233
|
```tsx
|
|
237
|
-
import { useCopyToClipboard } from
|
|
238
|
-
import { toast } from
|
|
234
|
+
import { useCopyToClipboard } from "@usefy/use-copy-to-clipboard";
|
|
235
|
+
import { toast } from "your-toast-library";
|
|
239
236
|
|
|
240
237
|
function CopyWithToast({ text }: { text: string }) {
|
|
241
238
|
const [, copy] = useCopyToClipboard({
|
|
@@ -254,22 +251,24 @@ function CopyWithToast({ text }: { text: string }) {
|
|
|
254
251
|
### Async Handling
|
|
255
252
|
|
|
256
253
|
```tsx
|
|
257
|
-
import { useCopyToClipboard } from
|
|
254
|
+
import { useCopyToClipboard } from "@usefy/use-copy-to-clipboard";
|
|
258
255
|
|
|
259
256
|
function AsyncCopy({ text }: { text: string }) {
|
|
260
257
|
const [, copy] = useCopyToClipboard();
|
|
261
|
-
const [status, setStatus] = useState<
|
|
258
|
+
const [status, setStatus] = useState<"idle" | "success" | "error">("idle");
|
|
262
259
|
|
|
263
260
|
const handleCopy = async () => {
|
|
264
261
|
const success = await copy(text);
|
|
265
|
-
setStatus(success ?
|
|
262
|
+
setStatus(success ? "success" : "error");
|
|
266
263
|
};
|
|
267
264
|
|
|
268
265
|
return (
|
|
269
266
|
<div>
|
|
270
267
|
<button onClick={handleCopy}>Copy</button>
|
|
271
|
-
{status ===
|
|
272
|
-
|
|
268
|
+
{status === "success" && (
|
|
269
|
+
<span className="success">Copied successfully!</span>
|
|
270
|
+
)}
|
|
271
|
+
{status === "error" && <span className="error">Failed to copy</span>}
|
|
273
272
|
</div>
|
|
274
273
|
);
|
|
275
274
|
}
|
|
@@ -278,7 +277,7 @@ function AsyncCopy({ text }: { text: string }) {
|
|
|
278
277
|
### Share URL Button
|
|
279
278
|
|
|
280
279
|
```tsx
|
|
281
|
-
import { useCopyToClipboard } from
|
|
280
|
+
import { useCopyToClipboard } from "@usefy/use-copy-to-clipboard";
|
|
282
281
|
|
|
283
282
|
function ShareButton() {
|
|
284
283
|
const [copiedText, copy] = useCopyToClipboard();
|
|
@@ -289,7 +288,7 @@ function ShareButton() {
|
|
|
289
288
|
|
|
290
289
|
return (
|
|
291
290
|
<button onClick={handleShare}>
|
|
292
|
-
{copiedText ?
|
|
291
|
+
{copiedText ? "Link Copied!" : "Share Link"}
|
|
293
292
|
</button>
|
|
294
293
|
);
|
|
295
294
|
}
|
|
@@ -298,7 +297,7 @@ function ShareButton() {
|
|
|
298
297
|
### Copy Multiple Items
|
|
299
298
|
|
|
300
299
|
```tsx
|
|
301
|
-
import { useCopyToClipboard } from
|
|
300
|
+
import { useCopyToClipboard } from "@usefy/use-copy-to-clipboard";
|
|
302
301
|
|
|
303
302
|
function CopyList({ items }: { items: string[] }) {
|
|
304
303
|
const [copiedText, copy] = useCopyToClipboard();
|
|
@@ -309,7 +308,7 @@ function CopyList({ items }: { items: string[] }) {
|
|
|
309
308
|
<li key={item}>
|
|
310
309
|
<span>{item}</span>
|
|
311
310
|
<button onClick={() => copy(item)}>
|
|
312
|
-
{copiedText === item ?
|
|
311
|
+
{copiedText === item ? "Copied!" : "Copy"}
|
|
313
312
|
</button>
|
|
314
313
|
</li>
|
|
315
314
|
))}
|
|
@@ -321,18 +320,18 @@ function CopyList({ items }: { items: string[] }) {
|
|
|
321
320
|
### API Key Display
|
|
322
321
|
|
|
323
322
|
```tsx
|
|
324
|
-
import { useCopyToClipboard } from
|
|
323
|
+
import { useCopyToClipboard } from "@usefy/use-copy-to-clipboard";
|
|
325
324
|
|
|
326
325
|
function ApiKeyDisplay({ apiKey }: { apiKey: string }) {
|
|
327
326
|
const [copiedText, copy] = useCopyToClipboard();
|
|
328
327
|
|
|
329
|
-
const maskedKey = `${apiKey.slice(0, 4)}${
|
|
328
|
+
const maskedKey = `${apiKey.slice(0, 4)}${"*".repeat(20)}${apiKey.slice(-4)}`;
|
|
330
329
|
|
|
331
330
|
return (
|
|
332
331
|
<div className="api-key">
|
|
333
332
|
<code>{maskedKey}</code>
|
|
334
333
|
<button onClick={() => copy(apiKey)}>
|
|
335
|
-
{copiedText === apiKey ?
|
|
334
|
+
{copiedText === apiKey ? "Copied!" : "Copy Key"}
|
|
336
335
|
</button>
|
|
337
336
|
</div>
|
|
338
337
|
);
|
|
@@ -351,7 +350,7 @@ import {
|
|
|
351
350
|
type UseCopyToClipboardOptions,
|
|
352
351
|
type UseCopyToClipboardReturn,
|
|
353
352
|
type CopyFn,
|
|
354
|
-
} from
|
|
353
|
+
} from "@usefy/use-copy-to-clipboard";
|
|
355
354
|
|
|
356
355
|
// Return type
|
|
357
356
|
const [copiedText, copy]: UseCopyToClipboardReturn = useCopyToClipboard();
|
|
@@ -362,8 +361,8 @@ const [copiedText, copy]: UseCopyToClipboardReturn = useCopyToClipboard();
|
|
|
362
361
|
// Options type
|
|
363
362
|
const options: UseCopyToClipboardOptions = {
|
|
364
363
|
timeout: 3000,
|
|
365
|
-
onSuccess: (text) => console.log(
|
|
366
|
-
onError: (error) => console.error(
|
|
364
|
+
onSuccess: (text) => console.log("Copied:", text),
|
|
365
|
+
onError: (error) => console.error("Error:", error),
|
|
367
366
|
};
|
|
368
367
|
```
|
|
369
368
|
|
|
@@ -373,14 +372,14 @@ const options: UseCopyToClipboardOptions = {
|
|
|
373
372
|
|
|
374
373
|
This hook uses the modern [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API) when available, with automatic fallback to `document.execCommand('copy')` for older browsers.
|
|
375
374
|
|
|
376
|
-
| Browser
|
|
377
|
-
|
|
378
|
-
| Chrome 66+
|
|
379
|
-
| Firefox 63+
|
|
380
|
-
| Safari 13.1+
|
|
381
|
-
| Edge 79+
|
|
382
|
-
| IE 11
|
|
383
|
-
| Older browsers | No
|
|
375
|
+
| Browser | Clipboard API | Fallback |
|
|
376
|
+
| -------------- | ------------- | -------- |
|
|
377
|
+
| Chrome 66+ | Yes | - |
|
|
378
|
+
| Firefox 63+ | Yes | - |
|
|
379
|
+
| Safari 13.1+ | Yes | - |
|
|
380
|
+
| Edge 79+ | Yes | - |
|
|
381
|
+
| IE 11 | No | Yes |
|
|
382
|
+
| Older browsers | No | Yes |
|
|
384
383
|
|
|
385
384
|
---
|
|
386
385
|
|
|
@@ -390,12 +389,12 @@ This package maintains comprehensive test coverage to ensure reliability and sta
|
|
|
390
389
|
|
|
391
390
|
### Test Coverage
|
|
392
391
|
|
|
393
|
-
| Category
|
|
394
|
-
|
|
392
|
+
| Category | Coverage |
|
|
393
|
+
| ---------- | -------------- |
|
|
395
394
|
| Statements | 87.87% (58/66) |
|
|
396
|
-
| Branches
|
|
397
|
-
| Functions
|
|
398
|
-
| Lines
|
|
395
|
+
| Branches | 79.16% (19/24) |
|
|
396
|
+
| Functions | 85.71% (6/7) |
|
|
397
|
+
| Lines | 87.87% (58/66) |
|
|
399
398
|
|
|
400
399
|
### Test Categories
|
|
401
400
|
|
|
@@ -447,14 +446,14 @@ pnpm test --coverage
|
|
|
447
446
|
|
|
448
447
|
Explore other hooks in the **@usefy** collection:
|
|
449
448
|
|
|
450
|
-
| Package
|
|
451
|
-
|
|
452
|
-
| [@usefy/use-local-storage](https://www.npmjs.com/package/@usefy/use-local-storage)
|
|
449
|
+
| Package | Description |
|
|
450
|
+
| -------------------------------------------------------------------------------------- | --------------------------- |
|
|
451
|
+
| [@usefy/use-local-storage](https://www.npmjs.com/package/@usefy/use-local-storage) | Persistent localStorage |
|
|
453
452
|
| [@usefy/use-session-storage](https://www.npmjs.com/package/@usefy/use-session-storage) | Session storage persistence |
|
|
454
|
-
| [@usefy/use-toggle](https://www.npmjs.com/package/@usefy/use-toggle)
|
|
455
|
-
| [@usefy/use-counter](https://www.npmjs.com/package/@usefy/use-counter)
|
|
456
|
-
| [@usefy/use-debounce](https://www.npmjs.com/package/@usefy/use-debounce)
|
|
457
|
-
| [@usefy/use-click-any-where](https://www.npmjs.com/package/@usefy/use-click-any-where) | Global click detection
|
|
453
|
+
| [@usefy/use-toggle](https://www.npmjs.com/package/@usefy/use-toggle) | Boolean state management |
|
|
454
|
+
| [@usefy/use-counter](https://www.npmjs.com/package/@usefy/use-counter) | Counter state management |
|
|
455
|
+
| [@usefy/use-debounce](https://www.npmjs.com/package/@usefy/use-debounce) | Value debouncing |
|
|
456
|
+
| [@usefy/use-click-any-where](https://www.npmjs.com/package/@usefy/use-click-any-where) | Global click detection |
|
|
458
457
|
|
|
459
458
|
---
|
|
460
459
|
|