-
Notifications
You must be signed in to change notification settings - Fork 647
feat(Spinner): add support for synchronized animations #7157
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
🦋 Changeset detectedLatest commit: b21ee3c The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
👋 Hi, this pull request contains changes to the source code that github/github-ui depends on. If you are GitHub staff, test these changes with github/github-ui using the integration workflow. Or, apply the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR updates the Spinner component to synchronize animations across all spinner instances using the Web Animations API instead of CSS animations. This ensures that multiple spinners rendered at different times maintain visual synchronization, creating a more polished user experience.
Key changes:
- Replaced CSS-based animations with JavaScript Web Animations API to enable synchronization
- Added
useSpinnerAnimationhook that setsstartTimeto 0 for all spinner instances - Maintained accessibility by respecting
prefers-reduced-motionpreference
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| packages/react/src/Spinner/Spinner.tsx | Implements Web Animations API-based animation synchronization via new useSpinnerAnimation hook |
| packages/react/src/Spinner/Spinner.module.css | Removes CSS keyframe animation since animation is now handled in JavaScript |
| packages/react/src/Spinner/Spinner.examples.stories.tsx | Adds SynchronizedSpinners story demonstrating the synchronization feature with delayed spinner mounts |
| .changeset/afraid-buckets-build.md | Documents the change as a minor version update |
|
@joshblack Did you see the css first implementation with little javascript in https://github.com/github/github-ui/pull/6120, it uses negative animation-delay which I thought was very smart |
|
@siddharthkp yeah! I didn't really know if it would synchronize accurately 🤔 When I tried it out and slowed it down they seemed to be off a bit: Screen.Recording.2025-11-12.at.3.37.56.PM.movThis could be related to test setup though. Definitely the faster the animation the less I can see it (if at all). I also wasn't sure what would happen with the difference between SSR / client hydration and if the spinner would jump if the delay changes between what is sent in the HTML payload versus hydration |
Seems super odd!
Valid, not sure if it matters in the case of spinners.
My (untested) guess is that it might start out of sync and then hydrate to be in sync. That would make a really cool demo! |
|
@siddharthkp let me know if there is anything else you'd like to see here 👀 The MDN docs seem to point out this limitation too:
|
Had a doubt that I should check first
Sorry just a question before I approve: Does this work with SSR or does it wait for the client bundle to start animation? If it's the later, then we're making the component worse and better at the same time. 😅 This should ideally act like a progressive enhancement |
|
Sharing this over from Slack in case folks are curious 👀 Hopefully this does the trick :fingers_crossed: It gets so weird to not cause jank when going from CSS -> JS 😅 I ended up doing something like:
|
|
👋 Hi from github/github-ui! Your integration PR is ready: https://github.com/github/github-ui/pull/8508 |
🔬 github-ui Integration Test Results
❌ Troubleshooting Failed ChecksCIThis check runs linting, type checking, and unit tests. Check the workflow logs for specific failures. Projects (Memex)This check runs Playwright end-to-end tests for the Projects feature. Check the test artifacts for screenshots and traces. Need help? If you believe this failure is unrelated to your changes, please reach out to the Primer team for assistance. |
Closes https://github.com/github/primer/issues/6105
Uses a technique from Spectrum to drive our Spinner animations so that they are always in sync: https://github.com/adobe/react-spectrum/blob/ab5e6f3dba4235dafab9f81f8b5c506ce5f11230/packages/%40react-spectrum/s2/src/Skeleton.tsx#L21
We build on top of this technique since we want spinners to also work during SSR -> hydration. As a result, this PR adds the following:
We use the Web Animations API to synchronize these since we cannot do this with CSS alone without introducing jank during the transition between CSS -> JS (at least none that I could find 😅)
Quick video with before/after with these changes:
Screen.Recording.2025-12-08.at.3.10.40.PM.mov
Changelog
New
Changed
Removed
Rollout strategy
We will roll this out behind a feature flag first and then stabilize as-needed