useCopyToClipboard
useCopyToClipboard
is a custom hook to copy text to the clipboard with optional callbacks and auto-reset functionality.
Syntax
const { copied, error, copy } = useCopyToClipboard(options?: CopyToClipboardOptions);
Props
The hook accepts an optional object of type CopyToClipboardOptions
:
Property | Type | Default | Description |
---|---|---|---|
resetTime | number | 1500 (ms) | Time in milliseconds to reset the copied state. |
onSuccess | (copiedText: string) => void | undefined | Callback function triggered when text is successfully copied to the clipboard. |
onError | (error: Error) => void | undefined | Callback function triggered when an error occurs during the copy operation. |
Return
An object containing the following properties:
Key | Type | Description |
---|---|---|
copied | boolean | Indicates whether the text was successfully copied to the clipboard. |
error | Error | null | Holds the error object if the copy operation fails; otherwise, it is null . |
copy | (text: string) => Promise<void> | A function that triggers the copy operation. Accepts the text to be copied as an argument. |
The Hook
useCopyToClipboard.ts
import { useCallback, useState } from "react";
interface CopyToClipboardState {
copied: boolean;
error: Error | null;
}
interface CopyToClipboardStateReturnType extends CopyToClipboardState {
copy: (text: string) => Promise<void>;
}
interface CopyToClipboardOptions {
resetTime?: number;
onSuccess?: (copiedText: string) => void;
onError?: (error: Error) => void;
}
export function useCopyToClipboard(
options: CopyToClipboardOptions = {}
): CopyToClipboardStateReturnType {
const { resetTime = 1500, onSuccess, onError } = options;
const [state, setState] = useState<CopyToClipboardState>({
copied: false,
error: null,
});
const copy = useCallback(async (text: string) => {
try {
if (!navigator?.clipboard) {
throw new Error("Clipboard API not supported");
}
await navigator.clipboard.writeText(text);
setState({ copied: true, error: null });
onSuccess?.(text);
setTimeout(() => {
setState((prev) => ({
...prev,
copied: false,
}));
}, resetTime);
} catch (error) {
const copyError =
error instanceof Error ? error : new Error("Failed to copy");
setState({ copied: false, error: copyError });
onError?.(copyError);
}
}, []);
return { ...state, copy };
}
Usage
Basic Example
import React from "react";
import { useCopyToClipboard } from "./hooks";
function CopyDemo() {
const { copied, error, copy } = useCopyToClipboard();
async function handleCopy() {
await copy("Hello, World!");
}
return (
<div>
<button onClick={handleCopy}>{copied ? "Copied!" : "Copy Text"}</button>
{error && <p>Error: {error.message}</p>}
</div>
);
}
Example with Callbacks and Custom Reset Time
import React from "react";
import { useCopyToClipboard } from "./hooks";
function CopyWithCallbacks() {
const { copied, error, copy } = useCopyToClipboard({
resetTime: 3000,
onSuccess: (text) => alert(`Successfully copied: ${text}`),
onError: (error) => alert(`Error copying: ${error.message}`),
});
async function handleCopy() {
await copy("Sample text for clipboard!");
}
return (
<div>
<button onClick={handleCopy}>
{copied ? "Copied!" : "Copy to Clipboard"}
</button>
{error && <p style={{ color: "red" }}>Error: {error.message}</p>}
</div>
);
}
Specifications
This hook utilizes the Clipboard API (opens in a new tab) to perform clipboard operations. Ensure that the browser supports this API for consistent functionality.
See Also
- Clipboard API on MDN (opens in a new tab)
- React
useCallback
(opens in a new tab) - React
useState
(opens in a new tab)
Last updated on November 23, 2024