Description
CopyButton swaps to a check icon after a click, but the check never reverts to the clipboard icon reliably. The 2s reset timer is started in a useEffect with an empty dependency array, so it runs once on mount, not when the user copies.
Where:
packages/ui/copy-button.tsx:26-30
useEffect(() => {
setTimeout(() => {
setHasCopied(false)
}, 2000)
}, [])
Steps to reproduce:
- Render
<CopyButton value="x" />.
- Wait more than 2 seconds.
- Click the button.
Expected behavior:
The check icon shows for about 2 seconds, then returns to the clipboard icon.
Actual behavior:
The check icon stays forever, because the only timer already fired on mount. Clicking before the mount timer fires has the opposite problem: the icon resets early, at 2s after mount rather than 2s after the click. The timer is also never cleared on unmount.
Suggested fix:
Run the effect on [hasCopied], only start the timeout when hasCopied is true, and return a clearTimeout cleanup. This is the same pattern CopyableCell already uses in packages/ui/copyable-cell.tsx:22-29:
useEffect(() => {
if (!hasCopied) return
const timeout = setTimeout(() => setHasCopied(false), 2000)
return () => clearTimeout(timeout)
}, [hasCopied])
Happy to send a PR for this if it's welcome.
Description
CopyButtonswaps to a check icon after a click, but the check never reverts to the clipboard icon reliably. The 2s reset timer is started in auseEffectwith an empty dependency array, so it runs once on mount, not when the user copies.Where:
packages/ui/copy-button.tsx:26-30Steps to reproduce:
<CopyButton value="x" />.Expected behavior:
The check icon shows for about 2 seconds, then returns to the clipboard icon.
Actual behavior:
The check icon stays forever, because the only timer already fired on mount. Clicking before the mount timer fires has the opposite problem: the icon resets early, at 2s after mount rather than 2s after the click. The timer is also never cleared on unmount.
Suggested fix:
Run the effect on
[hasCopied], only start the timeout whenhasCopiedis true, and return aclearTimeoutcleanup. This is the same patternCopyableCellalready uses inpackages/ui/copyable-cell.tsx:22-29:Happy to send a PR for this if it's welcome.