feat(CopyButton): inline copy-to-clipboard button with success flash - #397
Conversation
Ported from waggleline's row-level copy affordance: stops propagation so it is safe inside clickable rows, flashes a success check with configurable labels/timeout, and stays silent when clipboard access is denied. FontAwesome icons become lucide Copy/Check on semantic tokens.
There was a problem hiding this comment.
Pull request overview
Adds a new inline CopyButton component to the design system for row-level “copy to clipboard” affordances (IDs/emails/keys), and wires it into the library’s public exports and build entries.
Changes:
- Introduces
CopyButton(inline icon button) that writes a providedvalueto the clipboard and briefly flashes a success state. - Adds unit tests and Storybook stories for the new component.
- Exports the component from the package entrypoints and registers it in
tsupfor bundling.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tsup.config.ts | Adds a new tsup entrypoint for components/CopyButton. |
| src/index.ts | Re-exports CopyButton from the library root. |
| src/components/CopyButton/index.ts | Adds the component barrel export. |
| src/components/CopyButton/CopyButton.tsx | Implements the new copy-to-clipboard icon button. |
| src/components/CopyButton/CopyButton.test.tsx | Adds unit tests for copy/flash/revert/propagation/denied clipboard. |
| src/components/CopyButton/CopyButton.stories.tsx | Adds Storybook stories for inline and detail-field usage. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Deploying ui with
|
| Latest commit: |
e4b9450
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://4b0ad4d7.ui-6d0.pages.dev |
| Branch Preview URL: | https://feat-copy-button.ui-6d0.pages.dev |
…icit displayName - Tests stub navigator via vi.stubGlobal + vi.unstubAllGlobals (SuperChat pattern) instead of mutating the real global - Explicit CopyButton.displayName for DevTools parity with the library's forwardRef components
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.
Suppressed comments (2)
Previously missed (2) — in code that hasn't changed since the last review.
src/components/CopyButton/CopyButton.tsx:91
{...props}is spread aftertype,title, andaria-label, so callers can accidentally override these (e.g.type="submit"inside a form, or a fixedaria-labelthat never updates to "Copied"). Since this component intentionally forcestype="button"and manages its own accessible label, spread props earlier so the component-controlled attributes always win.
className
)}
{...props}
>
{copied ? (
src/components/CopyButton/CopyButton.tsx:34
- The docstring says “Stateless across instances”, but the component has internal state (
copied) and a timer; what you likely mean is that state is isolated per instance. Wording this accurately avoids confusion for consumers.
* An inline copy-to-clipboard icon button with a brief success check.
* Stateless across instances — safe to drop into table rows, ID chips,
* and detail fields.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
src/components/CopyButton/CopyButton.tsx:96
- The copied-state feedback is only conveyed by swapping
title/aria-labeland an icon witharia-hidden, which often won’t be announced to screen readers when the click succeeds. Add anaria-live/status announcement (visually hidden) so assistive tech users get explicit success feedback.
Ports waggleline's row-level copy affordance into the design system — the inline copy-to-clipboard button the library has been missing next to IDs, emails, phone numbers, and API keys.
What it does
valueto the clipboard and flashes a success check (copiedLabel, configurabletimeout), then revertsonCopiedcallback for toasts/analyticsScreenshots
Detail fields with the email just copied (success check showing):
Provenance
Port of
waggleline/app/imports/ui/components/CopyButton.tsx; FontAwesome → lucideCopy/Check, hardcoded grays → semantic tokens, plus asuccess-token flash, configurable labels, and anonCopiedhook.Testing
typecheck/lint/format/rtl:scanclean; combined batch suite 651/651