@mshafiqyajid/react-copy-button

v0.1.1 ~22 KB 0 deps react

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.

$ npm install @mshafiqyajid/react-copy-button

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

PropTypeDefaultDescription
textstring | () => string | Promise<string>Required. Text to copy.
labelReactNode"Copy"Default-state label.
copiedLabelReactNode"Copied"Label after copy.
variantsolid | outline | ghost | subtlesolidVisual variant.
sizesm | md | lg | iconmdSize.
toneneutral | primary | success | dangerneutralColor theme.
fullWidthbooleanfalseStretch to container.
iconboolean | { copy?, check? }trueShow/hide icon or pass custom.
loadingboolean | "auto""auto"Show spinner while async resolves.
tooltipReactNodeTooltip on hover/focus.
resetAfternumber (ms)2000Copied state duration.
onCopy(text: string) => voidCalled after successful copy.
onError(error: Error) => voidCalled on failure.
Edit this page on GitHub