Description
Stellar wallet addresses displayed in the app must be manually selected and copied, which is error-prone on mobile and desktop alike. Every address display should include a copy-to-clipboard button with a brief visual confirmation that the copy succeeded.
Technical Context
src/components/ui/CopyButton.tsx (new) wraps the navigator.clipboard.writeText API, falling back to document.execCommand('copy') for older browsers. The button toggles between a copy icon and a check icon from lucide-react for 2 seconds after a successful copy. src/components/invoice/RecipientRow.tsx, src/components/wallet/WalletAddress.tsx, and src/app/invoice/[id]/page.tsx all use this component. A useClipboard hook centralizes the copy logic and state.
Acceptance Criteria
Description
Stellar wallet addresses displayed in the app must be manually selected and copied, which is error-prone on mobile and desktop alike. Every address display should include a copy-to-clipboard button with a brief visual confirmation that the copy succeeded.
Technical Context
src/components/ui/CopyButton.tsx(new) wraps thenavigator.clipboard.writeTextAPI, falling back todocument.execCommand('copy')for older browsers. The button toggles between a copy icon and a check icon fromlucide-reactfor 2 seconds after a successful copy.src/components/invoice/RecipientRow.tsx,src/components/wallet/WalletAddress.tsx, andsrc/app/invoice/[id]/page.tsxall use this component. AuseClipboardhook centralizes the copy logic and state.Acceptance Criteria
navigator.clipboardis unavailable, the fallback silently attemptsexecCommandand shows the same confirmationaria-label="Copy address"and a tooltip showing "Copied!" on success