Skip to content

fix(ui): reset the CopyButton checkmark after each copy#1282

Open
abhay-codes07 wants to merge 1 commit into
supermemoryai:mainfrom
abhay-codes07:fix/ui-copy-button-reset
Open

fix(ui): reset the CopyButton checkmark after each copy#1282
abhay-codes07 wants to merge 1 commit into
supermemoryai:mainfrom
abhay-codes07:fix/ui-copy-button-reset

Conversation

@abhay-codes07

Copy link
Copy Markdown
Contributor

What

The CopyButton checkmark never resets. The reset timer runs once on mount with an empty dependency array — i.e. it fires (uselessly) two seconds after render, before any click — and nothing ever sets hasCopied back to false after a copy:

useEffect(() => {
    setTimeout(() => { setHasCopied(false) }, 2000)
}, [])

In the integrations install-steps (the component's consumer), the first copy click swaps the clipboard icon to a checkmark permanently; subsequent copies give no visual feedback at all.

Fix

Key the effect on hasCopied with proper cleanup — the same pattern the sibling copyable-cell.tsx already uses:

useEffect(() => {
    if (!hasCopied) return
    const timer = setTimeout(() => setHasCopied(false), 2000)
    return () => clearTimeout(timer)
}, [hasCopied])

Each copy now shows the checkmark for 2 seconds and reverts; rapid re-copies restart the window cleanly, and the stray mount-time timer is gone.

Testing

  • bun run build in apps/web (the consumer) — clean
  • biome check on the touched file — clean

The reset timer ran once on mount with an empty dependency array, so it
fired two seconds after render, before any click, and nothing ever set
hasCopied back to false afterwards. The first copy swapped the
clipboard icon to a checkmark permanently and later copies gave no
visual feedback.

Key the effect on hasCopied with a cleanup, the same pattern
copyable-cell.tsx already uses: every copy shows the checkmark for two
seconds and reverts, rapid re-copies restart the window, and the stray
mount-time timer is gone.
Copilot AI review requested due to automatic review settings July 13, 2026 05:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@ishaanxgupta

Copy link
Copy Markdown
Contributor

The changes are good but I could not reproduce this exact issue point, can you point me to the exact page where this file is being used?

I think this file (apps/web/components/integrations/install-steps.tsx) is being used for the copy button and here it has the correct reset behaviour.

@abhay-codes07

Copy link
Copy Markdown
Contributor Author

Good catch @ishaanxgupta, and you are right about install-steps.tsx. That file has its own local CopyButton with the correct reset behaviour, and this PR does not touch it.

The component fixed here is the shared one in packages/ui/copy-button.tsx. As far as I can tell it currently has no importers inside the monorepo (a grep for copy-button turns up nothing outside the package itself), which is why there is no page where you can reproduce it today. It has been in the ui package since the consumer app rewrite and survived a couple of refactors, so I fixed it in place rather than assuming it was safe to delete.

The bug itself: the reset effect runs once on mount instead of after a copy. The 2 second timer starts when the component first renders, so it fires while hasCopied is still false and does nothing. Any copy after that point shows a checkmark that never clears, and repeated copies never reset either. There is also no clearTimeout cleanup. The fix keys the effect on hasCopied with proper cleanup, so the first consumer that imports this component gets the expected behaviour.

If you would rather remove the component entirely since nothing imports it yet, I am happy to rework this PR into a deletion instead. Just let me know which way you want it.

@abhay-codes07

Copy link
Copy Markdown
Contributor Author

@ishaanxgupta here is the reproduction. Since nothing imports this shared component yet, there is no prod page to click, so I rendered the actual packages/ui/copy-button.tsx in a small harness: the current main version on the left, this PR's version on the right. Both are clicked at the same moment; the screenshot is taken 3 seconds later.

copy-button reset: main stays on the check, this PR resets

Left (main) is still stuck on the checkmark; right (this PR) has reset to the clipboard icon.

The reason it is easy to miss: the reset timer on main is keyed on [], so it runs once on mount and fires 2s after the component first renders, not after a copy. So the outcome depends on when you click:

  • Copy within ~2s of the page loading and the stray mount timer happens to fire right after, so it looks fine.
  • Copy any later than that (the normal case) and there is no timer left; the checkmark sticks indefinitely.
  • A second copy never resets either, because the single mount timer has already fired.

The harness clicks after the mount timer has elapsed, which is why main stays stuck. The fix keys the effect on [hasCopied] and clears the timer on cleanup, so every copy gets its own 2s reset. Happy to still fold this into a deletion instead if you would rather drop the unused component.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants