From a7c468152950c8d33b14f5168b354cf5f939c8b6 Mon Sep 17 00:00:00 2001 From: Persephone Flores <34418758+hp0844182@users.noreply.github.com> Date: Fri, 24 Oct 2025 01:28:43 +0800 Subject: [PATCH] fix: infinite loop in unmount causing browser crash - Extract unmount logic to avoid recursive self-calls in delayed unmount - Fix shouldDelay condition causing unmount to call itself infinitely - Ensure proper cleanup in both immediate and delayed unmount paths --- packages/motion/README.md | 132 +++++++++++++++++++++- packages/motion/src/state/motion-state.ts | 24 ++-- 2 files changed, 145 insertions(+), 11 deletions(-) mode change 120000 => 100644 packages/motion/README.md diff --git a/packages/motion/README.md b/packages/motion/README.md deleted file mode 120000 index fe84005..0000000 --- a/packages/motion/README.md +++ /dev/null @@ -1 +0,0 @@ -../../README.md \ No newline at end of file diff --git a/packages/motion/README.md b/packages/motion/README.md new file mode 100644 index 0000000..7be77c8 --- /dev/null +++ b/packages/motion/README.md @@ -0,0 +1,131 @@ +

Motion logo
Motion for Vue

+ +

+ + + + + + + + + +

+ +
+
+
+ +Motion for Vue is an open source, production-ready library that’s designed for all creative developers. + +It's the only animation library with a hybrid engine, combining the power of JavaScript animations with the performance of native browser APIs. + +It looks like this: + +```jsx + +``` + +It does all this: + +- Springs +- Keyframes +- Layout animations +- Shared layout animations +- Gestures (drag/tap/hover) +- Scroll animations +- SVG paths +- Exit animations +- Server-side rendering +- Independent transforms +- Orchestrate animations across components +- CSS variables + +...and a whole lot more. + +## Get started + +### πŸ‡ Quick start + +Install `motion-v` via your package manager: + +``` +npm install motion-v +``` + +Then import the `motion` component: + +```vue + + + +``` + +## ⚑️ Motion+ + +Learn, Design, Build. [Motion+](https://motion.dev/plus) is a one-time fee, lifetime update membership that provides: +- 160+ premium Motion Examples +- Motion UI features like Cursor and Ticker +- Motion Studio animation editing for VS Code `alpha` +- Early access content +- Private Discord + +[Get Motion+](https://motion.dev/plus) + +## 🎨 Studio + +![Video of bezier curve editing](https://framerusercontent.com/images/KO5dnHOUSNGb9S73p1J7nLhoFI.gif) + +Motion Studio is a versatile suite of developer tools allowing you to: + +- Visually edit CSS and Motion easing curves in VS Code +- Generate CSS springs with LLMs +- Load Motion docs into your LLM + +Get started with [Motion Studio](https://motion.dev/docs/tools-quick-start). + +### πŸ’Ž Contribute + +- Want to contribute to Motion? Our [contributing guide](https://github.com/motiondivision/motion-vue/blob/master/CONTRIBUTING.md) has you covered. +- [Join our discord ](https://discord.com/invite/dCBuRgdNDG) + +### πŸ‘©πŸ»β€βš–οΈ License + +- Motion for Vue is MIT licensed. + +## ✨ Sponsors + +Motion is sustainable thanks to the kind support of its sponsors. + +### Partners + +#### Framer + +Motion powers Framer animations, the web builder for creative pros. Design and ship your dream site. Zero code, maximum speed. + + + Framer + + +### Platinum + +Tailwind Linear + +### Gold + +Tailwind Emil Kowalski Liveblocks Vercel Luma Notion + +### Silver + +Frontend.fyi Firecrawl Puzzmo Bolt.new + +### Personal sponsors + +- [OlegWock](https://sinja.io) +- [Lambert Weller](https://github.com/l-mbert) +- [Jake LeBoeuf](https://jklb.wf) +- [Han Lee](https://github.com/hahnlee) diff --git a/packages/motion/src/state/motion-state.ts b/packages/motion/src/state/motion-state.ts index d83de6c..df55daa 100644 --- a/packages/motion/src/state/motion-state.ts +++ b/packages/motion/src/state/motion-state.ts @@ -169,21 +169,25 @@ export class MotionState { unmount(unMountChildren = false) { const shouldDelay = this.options.layoutId && this.visualElement.projection?.getStack().lead === this.visualElement.projection && this.visualElement.projection.isProjecting() + const unmountState = () => { + if (unMountChildren) { + Array.from(this.children).reverse().forEach(this.unmountChild) + } + this.parent?.children?.delete(this) + mountedStates.delete(this.element) + this.featureManager.unmount() + this.visualElement?.unmount() + // clear animation + this.clearAnimation() + } if (shouldDelay) { Promise.resolve().then(() => { - this.unmount(unMountChildren) + unmountState() }) - return } - if (unMountChildren) { - Array.from(this.children).reverse().forEach(this.unmountChild) + else { + unmountState() } - this.parent?.children?.delete(this) - mountedStates.delete(this.element) - this.featureManager.unmount() - this.visualElement?.unmount() - // clear animation - this.clearAnimation() } private unmountChild(child: MotionState) {