UNPKG

motion-v

Version:

<h1 align="center"> <img width="35" height="35" alt="Motion logo" src="https://github.com/user-attachments/assets/00d6d1c3-72c4-4c2f-a664-69da13182ffc" /><br />Motion for Vue</h1>

117 lines (116 loc) 3.82 kB
import { lazyFeatures } from "../features/lazy-features.mjs"; import { isSVGElement, resolveInitialValues } from "./utils.mjs"; import { motionGlobalConfig } from "../config.mjs"; import { frame, isVariantLabel } from "motion-dom"; import { invariant } from "hey-listen"; const mountedStates = /* @__PURE__ */ new WeakMap(); var MotionState = class { constructor(options, parent) { this.element = null; this.isExiting = false; this.presenceContainer = null; this.children = /* @__PURE__ */ new Set(); this.features = /* @__PURE__ */ new Map(); this._context = null; this.options = options; this.parent = parent; parent?.children?.add(this); this.latestValues = resolveInitialValues(options, this.context); this.type = isSVGElement(this.options.as) ? "svg" : "html"; } get context() { if (!this._context) this._context = new Proxy({}, { get: (target, prop) => { const value = this.options[prop]; if (isVariantLabel(value) || prop === "initial" && value === false) return value; return this.parent?.context[prop]; } }); return this._context; } updateFeatures() { if (!this.visualElement) return; for (const FeatureCtor of lazyFeatures) { if (!this.features.has(FeatureCtor.key)) this.features.set(FeatureCtor.key, new FeatureCtor(this)); const feature = this.features.get(FeatureCtor.key); if (this.isMounted()) if (!feature.isMount) { feature.mount(); feature.isMount = true; } else feature.update(); } } updateOptions(options) { this.options = options; this.visualElement?.update({ ...this.options, whileTap: this.options.whilePress }, this.options.presenceContext ?? null); } mount(element) { invariant(Boolean(element), "Animation state must be mounted with valid Element"); mountedStates.set(element, this); this.element = element; const presenceId = this.options.presenceContext?.presenceId; if (presenceId !== void 0) element.setAttribute(motionGlobalConfig.motionAttribute, presenceId); this.visualElement?.mount(element); this.updateFeatures(); } beforeUnmount() { this.getSnapshot(this.options, false); } unmount() { this.parent?.children?.delete(this); mountedStates.delete(this.element); this.features.forEach((f) => f.unmount?.()); this.visualElement?.unmount(); } beforeUpdate() { this.getSnapshot(this.options, void 0); } update() { this.updateFeatures(); this.didUpdate(); } tryExitComplete() { if (this.isExiting) return; if (this.options?.layoutId && this.visualElement.projection?.currentAnimation?.state === "running") return; this.options.presenceContext?.onMotionExitComplete?.(this.presenceContainer, this); } setActive(name, isActive) { if (name === "exit" && isActive) this.isExiting = true; this.visualElement?.animationState?.setActive(name, isActive).then(() => { if (name === "exit" && isActive) { this.isExiting = false; this.options?.layoutId ? frame.postRender(() => this.tryExitComplete()) : this.tryExitComplete(); } }); } isMounted() { return Boolean(this.element); } initVisualElement(renderer) { if (this.visualElement) return; this.visualElement = renderer(this.options.as, { presenceContext: this.options.presenceContext ?? null, parent: this.parent?.visualElement, props: { ...this.options, whileTap: this.options.whilePress }, visualState: { renderState: { transform: {}, transformOrigin: {}, style: {}, vars: {}, attrs: {} }, latestValues: { ...this.latestValues } }, reducedMotionConfig: this.options.motionConfig?.reducedMotion }); this.visualElement.parent?.addChild(this.visualElement); if (this.isMounted()) this.visualElement.mount(this.element); } getSnapshot(options, isPresent) {} didUpdate() {} }; export { MotionState, mountedStates };