Skip to content

fix(ripple-button): clean up overlapping ripples independently - #1020

Merged
Yeom-JinHo merged 2 commits into
magicuidesign:mainfrom
xpeng5278-web:fix/ripple-button-cleanup
Oct 17, 2026
Merged

Yeom-JinHo merged 2 commits into
magicuidesign:mainfrom
xpeng5278-web:fix/ripple-button-cleanup

Conversation

@xpeng5278-web

Copy link
Copy Markdown
Contributor

Fixes #1019

Summary

Fixes the RippleButton cleanup backlog: each new click was canceling the previous ripple's removal timer, so expired nodes accumulated during rapid clicks and then drained one-per-duration after input stopped.

What

  • Replaces the array-wide "latest ripple only" useEffect timeout with a small internal Ripple child that owns its own cleanup timer and calls a stable removeRipple(key) callback.
  • Adding or removing a different ripple no longer resets other ripples' lifetimes; unmount clears each outstanding timer.
  • Uses a monotonic key instead of Date.now() so rapid clicks in the same millisecond do not collide.
  • Regenerates apps/www/public/r/ripple-button.json and apps/www/public/llms-full.txt via pnpm build:registry.

Why

With default duration="600ms", click at t=0 and t=100 ms: both animations finish by t=700 ms, but main retained 1 node. Twenty clicks spaced 100 ms apart left 19 expired nodes after one more duration. #909 fixed missing --duration for animation; cleanup scheduling was unchanged.

How tested

Against unmodified main (cdb348cb):

  • single click → 0 after 601 ms (pass)
  • two clicks 100 ms apart → retained 1 after 601 ms (fail)
  • twenty clicks 100 ms apart → retained 19 (fail)

With this branch:

  • single click removes after duration
  • overlapping clicks: first gone at t=601, both gone at t=701
  • twenty rapid clicks leave 0 after another 601 ms
  • unmount clears outstanding timers (vi.getTimerCount() === 0)
  • consumer onClick still fires once per click

Repo gates:

  • pnpm check (lint, typecheck, format:check, registry-deps:check) ✅
  • pnpm build:registry ✅
  • pnpm build ✅

Notes

Distinct from #908/#909 (animation duration CSS variable). No changes to the background Ripple component or button styling API.

Give each ripple its own cleanup timer so later clicks do not cancel
earlier removals. Regenerate the installable registry payload.
@vercel

vercel Bot commented Oct 10, 2026

Copy link
Copy Markdown

@xpeng5278-web is attempting to deploy a commit to the product-studio Team on Vercel.

A member of the Team first needs to authorize it.

@Yeom-JinHo
Yeom-JinHo self-requested a review October 11, 2026 11:34

@Yeom-JinHo Yeom-JinHo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@xpeng5278-web
Thanks for the fix and the thorough repro! Confirmed the behavior locally.

I pushed one small commit on top (2b2a676) renaming the internal Ripple component to ButtonRipple to avoid confusion with the exported Ripple background component. No behavior change.

@Yeom-JinHo
Yeom-JinHo merged commit efe76fc into magicuidesign:main Oct 17, 2026
6 of 7 checks passed
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.

[bug]: RippleButton retains expired ripples during repeated clicks

2 participants