@mshafiqyajid/react-copy-button
Headless copy-to-clipboard hook and styled button primitive for React. Zero dependencies, SSR-safe, fully typed. Both a useCopyToClipboard() hook and a polished <CopyButtonStyled> with variants, sizes, tones, async source, tooltip, and animated copied state.
Playground #
Props
TSX
import { CopyButtonStyled } from "@mshafiqyajid/react-copy-button/styled";
import "@mshafiqyajid/react-copy-button/styles.css";
<CopyButtonStyled
text="Hello world"
tone="primary"
/>Install #
npm install @mshafiqyajid/react-copy-button Quick start #
Styled
import { CopyButtonStyled } from "@mshafiqyajid/react-copy-button/styled";
import "@mshafiqyajid/react-copy-button/styles.css";
<CopyButtonStyled text="hello world" tone="primary" /> Headless hook
import { useCopyToClipboard } from "@mshafiqyajid/react-copy-button";
const { copy, copied } = useCopyToClipboard({ resetAfter: 2000 });
<button onClick={() => void copy("hello")}>
{copied ? "Copied!" : "Copy"}
</button> Recipes #
Async source (e.g. token fetch)
<CopyButtonStyled
text={async () => {
const token = await fetchToken();
return token;
}}
label="Generate & copy"
tone="primary"
/> Custom icon
<CopyButtonStyled
text="hello"
icon={{ copy: <CopyIcon />, check: <CheckIcon /> }}
/> Render-prop for full control
import { CopyButton } from "@mshafiqyajid/react-copy-button";
<CopyButton text="hello world">
{({ copied, copy }) => (
<button onClick={copy} className="my-styled-button">
{copied ? "✓ Copied" : "Click to copy"}
</button>
)}
</CopyButton> API #
CopyButtonStyled
| Prop | Type | Default | Description |
|---|---|---|---|
| text | string | () => string | Promise<string> | — | Required. Text to copy. |
| label | ReactNode | "Copy" | Default-state label. |
| copiedLabel | ReactNode | "Copied" | Label after copy. |
| variant | solid | outline | ghost | subtle | solid | Visual variant. |
| size | sm | md | lg | icon | md | Size. |
| tone | neutral | primary | success | danger | neutral | Color theme. |
| fullWidth | boolean | false | Stretch to container. |
| icon | boolean | { copy?, check? } | true | Show/hide icon or pass custom. |
| loading | boolean | "auto" | "auto" | Show spinner while async resolves. |
| tooltip | ReactNode | — | Tooltip on hover/focus. |
| resetAfter | number (ms) | 2000 | Copied state duration. |
| onCopy | (text: string) => void | — | Called after successful copy. |
| onError | (error: Error) => void | — | Called on failure. |