motion-v 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/cjs/index.js +280 -134
  2. package/dist/es/animation/hooks/animation-controls.mjs +78 -0
  3. package/dist/es/animation/{use-animate.mjs → hooks/use-animate.mjs} +1 -1
  4. package/dist/es/animation/hooks/use-animation-controls.mjs +16 -0
  5. package/dist/es/animation/utils.mjs +6 -0
  6. package/dist/es/components/animate-presence/AnimatePresence.vue.mjs +2 -2
  7. package/dist/es/components/motion/Motion.vue.mjs +4 -1
  8. package/dist/es/constants/index.mjs +0 -1
  9. package/dist/es/features/animation/animation.mjs +33 -0
  10. package/dist/es/features/feature-manager.mjs +5 -1
  11. package/dist/es/features/gestures/focus/index.mjs +36 -0
  12. package/dist/es/index.mjs +3 -1
  13. package/dist/es/state/animate-updates.mjs +129 -0
  14. package/dist/es/state/motion-state.mjs +6 -123
  15. package/dist/es/state/style.mjs +2 -2
  16. package/dist/src/animation/hooks/animation-controls.d.ts +8 -0
  17. package/dist/src/animation/hooks/use-animate.d.ts +8 -0
  18. package/dist/src/animation/hooks/use-animation-controls.d.ts +33 -0
  19. package/dist/src/animation/index.d.ts +2 -1
  20. package/dist/src/animation/types.d.ts +68 -0
  21. package/dist/src/animation/utils.d.ts +2 -0
  22. package/dist/src/components/animate-presence/utils.d.ts +0 -1
  23. package/dist/src/components/index.d.ts +1 -1
  24. package/dist/src/components/motion/NameSpace.d.ts +2 -2
  25. package/dist/src/features/animation/animation.d.ts +13 -0
  26. package/dist/src/features/gestures/focus/index.d.ts +7 -0
  27. package/dist/src/features/gestures/focus/types.d.ts +6 -0
  28. package/dist/src/features/index.d.ts +1 -0
  29. package/dist/src/state/animate-updates.d.ts +19 -0
  30. package/dist/src/state/animation/types.d.ts +0 -0
  31. package/dist/src/state/motion-state.d.ts +2 -4
  32. package/dist/src/state/utils.d.ts +1 -1
  33. package/dist/src/types/state.d.ts +4 -2
  34. package/package.json +3 -2
  35. package/dist/es/components/animate-presence/utils.mjs +0 -10
  36. /package/dist/src/{animation/use-animation.d.ts → state/animation/index.d.ts} +0 -0
@@ -0,0 +1,33 @@
1
+ import { isAnimationControls } from "../../animation/utils.mjs";
2
+ import { Feature } from "../feature.mjs";
3
+ class AnimationFeature extends Feature {
4
+ constructor(state) {
5
+ super(state);
6
+ }
7
+ updateAnimationControlsSubscription() {
8
+ const { animate } = this.state.options;
9
+ if (isAnimationControls(animate)) {
10
+ this.unmountControls = animate.subscribe(this.state);
11
+ }
12
+ }
13
+ /**
14
+ * Subscribe any provided AnimationControls to the component's VisualElement
15
+ */
16
+ mount() {
17
+ this.updateAnimationControlsSubscription();
18
+ }
19
+ update() {
20
+ const { animate } = this.state.options;
21
+ const { animate: prevAnimate } = this.state.visualElement.prevProps || {};
22
+ if (animate !== prevAnimate) {
23
+ this.updateAnimationControlsSubscription();
24
+ }
25
+ }
26
+ unmount() {
27
+ var _a;
28
+ (_a = this.unmountControls) == null ? void 0 : _a.call(this);
29
+ }
30
+ }
31
+ export {
32
+ AnimationFeature
33
+ };
@@ -1,7 +1,9 @@
1
1
  import { SVGFeature } from "./svg.mjs";
2
2
  import { LayoutFeature } from "./layout/layout.mjs";
3
3
  import { PanGesture } from "./gestures/pan/index.mjs";
4
+ import { AnimationFeature } from "./animation/animation.mjs";
4
5
  import { ProjectionFeature } from "./layout/projection.mjs";
6
+ import { FocusGesture } from "./gestures/focus/index.mjs";
5
7
  import { HoverGesture } from "./gestures/hover/index.mjs";
6
8
  import { PressGesture } from "./gestures/press/index.mjs";
7
9
  import { InViewGesture } from "./gestures/in-view/index.mjs";
@@ -17,7 +19,9 @@ class FeatureManager {
17
19
  new LayoutFeature(state),
18
20
  new ProjectionFeature(state),
19
21
  new PanGesture(state),
20
- new DragGesture(state)
22
+ new DragGesture(state),
23
+ new FocusGesture(state),
24
+ new AnimationFeature(state)
21
25
  ];
22
26
  }
23
27
  mount() {
@@ -0,0 +1,36 @@
1
+ import { addDomEvent } from "../../../events/add-dom-event.mjs";
2
+ import { Feature } from "../../feature.mjs";
3
+ import { pipe } from "../../../external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/utils/pipe.mjs";
4
+ class FocusGesture extends Feature {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.isActive = false;
8
+ }
9
+ onFocus() {
10
+ let isFocusVisible = false;
11
+ try {
12
+ isFocusVisible = this.state.element.matches(":focus-visible");
13
+ } catch (e) {
14
+ isFocusVisible = true;
15
+ }
16
+ if (!isFocusVisible)
17
+ return;
18
+ this.state.setActive("focus", true);
19
+ this.isActive = true;
20
+ }
21
+ onBlur() {
22
+ if (!this.isActive)
23
+ return;
24
+ this.state.setActive("focus", false);
25
+ this.isActive = false;
26
+ }
27
+ mount() {
28
+ this.unmount = pipe(
29
+ addDomEvent(this.state.element, "focus", () => this.onFocus()),
30
+ addDomEvent(this.state.element, "blur", () => this.onBlur())
31
+ );
32
+ }
33
+ }
34
+ export {
35
+ FocusGesture
36
+ };
package/dist/es/index.mjs CHANGED
@@ -50,7 +50,8 @@ import { useMotionValueEvent } from "./value/use-motion-value-event.mjs";
50
50
  import { useSpring } from "./value/use-spring.mjs";
51
51
  import { useScroll } from "./value/use-scroll.mjs";
52
52
  import { useVelocity } from "./value/use-velocity.mjs";
53
- import { useAnimate } from "./animation/use-animate.mjs";
53
+ import { useAnimate } from "./animation/hooks/use-animate.mjs";
54
+ import { useAnimationControls } from "./animation/hooks/use-animation-controls.mjs";
54
55
  import { createContext } from "./utils/createContext.mjs";
55
56
  import { isMotionValue } from "./utils/motion-value.mjs";
56
57
  import { useInView } from "./utils/use-in-view.mjs";
@@ -120,6 +121,7 @@ export {
120
121
  time,
121
122
  transform,
122
123
  useAnimate,
124
+ useAnimationControls,
123
125
  useAnimationFrame,
124
126
  useCombineMotionValues,
125
127
  useComputed,
@@ -0,0 +1,129 @@
1
+ import { resolveVariant, getOptions, hasChanged } from "./utils.mjs";
2
+ import { style } from "./style.mjs";
3
+ import { transformResetValue } from "./transform.mjs";
4
+ import { motionEvent } from "./event.mjs";
5
+ import { isDef } from "@vueuse/core";
6
+ import { isAnimationControls } from "../animation/utils.mjs";
7
+ import { animate } from "../external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/animation/animate/index.mjs";
8
+ import { noop } from "../external/.pnpm/motion-utils@11.16.0/external/motion-utils/dist/es/noop.mjs";
9
+ import "../external/.pnpm/motion-utils@11.16.0/external/motion-utils/dist/es/errors.mjs";
10
+ const STATE_TYPES = ["initial", "animate", "inView", "hover", "press", "whileDrag", "focus", "exit"];
11
+ function animateUpdates({
12
+ controlActiveState = void 0,
13
+ controlDelay = 0,
14
+ directAnimate,
15
+ directTransition,
16
+ isFallback = false
17
+ } = {}) {
18
+ const prevTarget = this.target;
19
+ this.target = { ...this.baseTarget };
20
+ const animationOptions = {};
21
+ const transition = { ...this.options.transition };
22
+ if (directAnimate)
23
+ resolveDirectAnimation.call(this, directAnimate, directTransition, animationOptions);
24
+ else
25
+ resolveStateAnimation.call(this, controlActiveState, animationOptions);
26
+ const factories = createAnimationFactories.call(this, prevTarget, animationOptions, controlDelay);
27
+ const { getChildAnimations, childAnimations } = setupChildAnimations.call(this, transition, controlActiveState, isFallback);
28
+ return executeAnimations.call(this, factories, getChildAnimations, childAnimations, transition, controlActiveState);
29
+ }
30
+ function resolveDirectAnimation(directAnimate, directTransition, animationOptions) {
31
+ const variant = resolveVariant(directAnimate, this.options.variants, this.options.custom);
32
+ if (!variant)
33
+ return;
34
+ const transition = { ...this.options.transition, ...directTransition || variant.transition };
35
+ Object.entries(variant).forEach(([key, value]) => {
36
+ if (key === "transition")
37
+ return;
38
+ this.target[key] = value;
39
+ animationOptions[key] = getOptions(transition, key);
40
+ });
41
+ }
42
+ function resolveStateAnimation(controlActiveState, animationOptions) {
43
+ if (controlActiveState)
44
+ this.activeStates = { ...this.activeStates, ...controlActiveState };
45
+ STATE_TYPES.forEach((name) => {
46
+ if (!this.activeStates[name] || isAnimationControls(this.options[name]))
47
+ return;
48
+ const definition = isDef(this.options[name]) ? this.options[name] : this.context[name];
49
+ const variant = resolveVariant(definition, this.options.variants, this.options.custom);
50
+ if (!variant)
51
+ return;
52
+ const transition = { ...this.options.transition, ...variant.transition };
53
+ Object.entries(variant).forEach(([key, value]) => {
54
+ if (key === "transition")
55
+ return;
56
+ this.target[key] = value;
57
+ animationOptions[key] = getOptions(transition, key);
58
+ });
59
+ });
60
+ }
61
+ function createAnimationFactories(prevTarget, animationOptions, controlDelay) {
62
+ const factories = [];
63
+ new Set(Object.keys(this.target)).forEach((key) => {
64
+ var _a;
65
+ if (!hasChanged(this.visualElement.getValue(key), this.target[key]))
66
+ return;
67
+ (_a = this.baseTarget)[key] ?? (_a[key] = style.get(this.element, key));
68
+ const keyValue = this.target[key] === "none" ? transformResetValue[key] : this.target[key];
69
+ const targetTransition = animationOptions[key];
70
+ factories.push(() => animate(
71
+ this.element,
72
+ { [key]: keyValue },
73
+ {
74
+ ...targetTransition,
75
+ delay: ((targetTransition == null ? void 0 : targetTransition.delay) || 0) + controlDelay
76
+ }
77
+ ));
78
+ });
79
+ return factories;
80
+ }
81
+ function setupChildAnimations(transition, controlActiveState, isFallback) {
82
+ var _a;
83
+ if (!((_a = this.visualElement.variantChildren) == null ? void 0 : _a.size) || controlActiveState)
84
+ return { getChildAnimations: () => Promise.resolve(), childAnimations: [] };
85
+ const { staggerChildren = 0, staggerDirection = 1, delayChildren = 0 } = transition || {};
86
+ const maxStaggerDuration = (this.visualElement.variantChildren.size - 1) * staggerChildren;
87
+ const generateStaggerDuration = staggerDirection === 1 ? (i = 0) => i * staggerChildren : (i = 0) => maxStaggerDuration - i * staggerChildren;
88
+ const childAnimations = Array.from(this.visualElement.variantChildren).map((child, index) => {
89
+ const childDelay = delayChildren + generateStaggerDuration(index);
90
+ return child.state.animateUpdates({
91
+ controlActiveState: this.activeStates,
92
+ controlDelay: isFallback ? 0 : childDelay
93
+ });
94
+ }).filter(Boolean);
95
+ return {
96
+ getChildAnimations: () => Promise.all(childAnimations.map((animation) => animation())),
97
+ childAnimations
98
+ };
99
+ }
100
+ function executeAnimations(factories, getChildAnimations, childAnimations, transition, controlActiveState) {
101
+ let animations;
102
+ const getAnimation = () => {
103
+ animations = factories.map((factory) => factory()).filter(Boolean);
104
+ return Promise.all(animations);
105
+ };
106
+ const isExit = this.activeStates.exit;
107
+ const animationTarget = { ...this.target };
108
+ const element = this.element;
109
+ const finishAnimation = (animationPromise) => {
110
+ if (!(animations == null ? void 0 : animations.length) && !childAnimations.length) {
111
+ if (isExit) {
112
+ element.dispatchEvent(motionEvent("motionstart", animationTarget));
113
+ element.dispatchEvent(motionEvent("motioncomplete", animationTarget, isExit));
114
+ }
115
+ return;
116
+ }
117
+ element.dispatchEvent(motionEvent("motionstart", animationTarget));
118
+ animationPromise.then(() => element.dispatchEvent(motionEvent("motioncomplete", animationTarget, isExit))).catch(noop);
119
+ };
120
+ const getAnimationPromise = () => {
121
+ const animationPromise = (transition == null ? void 0 : transition.when) ? (transition.when === "beforeChildren" ? getAnimation() : getChildAnimations()).then(() => transition.when === "beforeChildren" ? getChildAnimations() : getAnimation()) : Promise.all([getAnimation(), getChildAnimations()]);
122
+ finishAnimation(animationPromise);
123
+ return animationPromise;
124
+ };
125
+ return controlActiveState ? getAnimationPromise : getAnimationPromise();
126
+ }
127
+ export {
128
+ animateUpdates
129
+ };
@@ -1,18 +1,12 @@
1
1
  import { invariant } from "hey-listen";
2
2
  import { visualElementStore } from "../external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/render/store.mjs";
3
3
  import { isDef } from "@vueuse/core";
4
- import { resolveVariant, getOptions, hasChanged } from "./utils.mjs";
4
+ import { resolveVariant } from "./utils.mjs";
5
5
  import { FeatureManager } from "../features/feature-manager.mjs";
6
- import { style } from "./style.mjs";
7
- import { transformResetValue } from "./transform.mjs";
8
- import { motionEvent } from "./event.mjs";
9
6
  import { createVisualElement } from "./create-visual-element.mjs";
10
7
  import { doneCallbacks } from "../components/presence.mjs";
8
+ import { animateUpdates } from "./animate-updates.mjs";
11
9
  import { frame } from "../external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/frameloop/frame.mjs";
12
- import { noop } from "../external/.pnpm/motion-utils@11.16.0/external/motion-utils/dist/es/noop.mjs";
13
- import "../external/.pnpm/motion-utils@11.16.0/external/motion-utils/dist/es/errors.mjs";
14
- import { animate } from "../external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/animation/animate/index.mjs";
15
- const STATE_TYPES = ["initial", "animate", "inView", "hover", "press", "whileDrag", "exit"];
16
10
  const mountedStates = /* @__PURE__ */ new WeakMap();
17
11
  let id = 0;
18
12
  class MotionState {
@@ -27,6 +21,7 @@ class MotionState {
27
21
  animate: true
28
22
  };
29
23
  this._context = null;
24
+ this.animateUpdates = animateUpdates;
30
25
  this.id = `motion-state-${id++}`;
31
26
  this.options = options;
32
27
  this.parent = parent;
@@ -176,122 +171,10 @@ class MotionState {
176
171
  child.state.setActive(name, isActive, false);
177
172
  });
178
173
  if (isAnimate) {
179
- this.animateUpdates();
180
- }
181
- }
182
- // Core animation update logic
183
- animateUpdates(controlActiveState = void 0, controlDelay = 0) {
184
- var _a;
185
- const prevTarget = this.target;
186
- this.target = {
187
- ...this.baseTarget
188
- };
189
- const animationOptions = {};
190
- let transition;
191
- if (controlActiveState) {
192
- this.activeStates = { ...this.activeStates, ...controlActiveState };
193
- }
194
- for (const name of STATE_TYPES) {
195
- if (!this.activeStates[name]) {
196
- continue;
197
- }
198
- const definition = isDef(this.options[name]) ? this.options[name] : this.context[name];
199
- const variant = resolveVariant(
200
- definition,
201
- this.options.variants,
202
- this.options.custom
203
- );
204
- transition = Object.assign({}, this.options.transition, variant == null ? void 0 : variant.transition);
205
- if (!variant)
206
- continue;
207
- const allTarget = { ...variant };
208
- for (const key in allTarget) {
209
- if (key === "transition")
210
- continue;
211
- this.target[key] = variant[key];
212
- animationOptions[key] = getOptions(
213
- transition,
214
- key
215
- );
216
- }
217
- }
218
- const allTargetKeys = /* @__PURE__ */ new Set([
219
- ...Object.keys(this.target)
220
- ]);
221
- const animationFactories = [];
222
- allTargetKeys.forEach((key) => {
223
- var _a2;
224
- if (hasChanged(prevTarget[key], this.target[key])) {
225
- (_a2 = this.baseTarget)[key] ?? (_a2[key] = style.get(this.element, key));
226
- const keyValue = this.target[key] === "none" ? transformResetValue[key] : this.target[key];
227
- const targetTransition = animationOptions[key];
228
- animationFactories.push(
229
- () => {
230
- return animate(
231
- this.element,
232
- {
233
- [key]: keyValue
234
- },
235
- {
236
- ...targetTransition,
237
- delay: ((targetTransition == null ? void 0 : targetTransition.delay) || 0) + controlDelay
238
- }
239
- );
240
- }
241
- );
242
- }
243
- });
244
- let getChildAnimations = () => Promise.resolve();
245
- let childAnimations = [];
246
- if (((_a = this.visualElement.variantChildren) == null ? void 0 : _a.size) && !controlActiveState) {
247
- const { staggerChildren = 0, staggerDirection = 1, delayChildren = 0 } = transition || {};
248
- const maxStaggerDuration = (this.visualElement.variantChildren.size - 1) * staggerChildren;
249
- const generateStaggerDuration = staggerDirection === 1 ? (i = 0) => i * staggerChildren : (i = 0) => maxStaggerDuration - i * staggerChildren;
250
- childAnimations = Array.from(this.visualElement.variantChildren).map((child, index) => {
251
- const childDelay = delayChildren + generateStaggerDuration(index);
252
- return child.state.animateUpdates(this.activeStates, childDelay);
253
- }).filter(Boolean);
254
- getChildAnimations = () => Promise.all(childAnimations.map((animation) => animation()));
255
- }
256
- let animations;
257
- const getAnimation = () => {
258
- animations = animationFactories.map((factory) => factory()).filter(Boolean);
259
- return Promise.all(animations);
260
- };
261
- const { when } = transition;
262
- let animationPromise;
263
- const isExit = this.activeStates.exit;
264
- const animationTarget = { ...this.target };
265
- const element = this.element;
266
- function finishAnimation() {
267
- if (!(animations == null ? void 0 : animations.length) && !childAnimations.length) {
268
- if (isExit) {
269
- element.dispatchEvent(motionEvent("motionstart", animationTarget));
270
- element.dispatchEvent(motionEvent("motioncomplete", animationTarget, isExit));
271
- }
272
- return;
273
- }
274
- element.dispatchEvent(motionEvent("motionstart", animationTarget));
275
- animationPromise.then(() => {
276
- element.dispatchEvent(motionEvent("motioncomplete", animationTarget, isExit));
277
- }).catch(noop);
278
- }
279
- function getAnimationPromise() {
280
- if (when) {
281
- const [first, last] = when === "beforeChildren" ? [getAnimation, getChildAnimations] : [getChildAnimations, getAnimation];
282
- animationPromise = first().then(() => last());
283
- finishAnimation();
284
- return animationPromise;
285
- } else {
286
- animationPromise = Promise.all([getAnimation(), getChildAnimations()]);
287
- finishAnimation();
288
- return animationPromise;
289
- }
290
- }
291
- if (controlActiveState) {
292
- return getAnimationPromise;
174
+ this.animateUpdates({
175
+ isFallback: !isActive
176
+ });
293
177
  }
294
- getAnimationPromise();
295
178
  }
296
179
  isMounted() {
297
180
  return Boolean(this.element);
@@ -1,5 +1,5 @@
1
- import { isCssVar, isNumber } from "./utils.mjs";
2
- import { transformDefinitions, isTransform, transformAlias, buildTransformTemplate } from "./transform.mjs";
1
+ import { isNumber, isCssVar } from "./utils.mjs";
2
+ import { isTransform, transformAlias, transformDefinitions, buildTransformTemplate } from "./transform.mjs";
3
3
  import { isMotionValue } from "../utils/motion-value.mjs";
4
4
  const style = {
5
5
  get: (element, name) => {
@@ -0,0 +1,8 @@
1
+ import { AnimationControls } from '../types';
2
+ import { MotionState } from '../../state';
3
+ import { Options } from '../../types';
4
+ /**
5
+ * @public
6
+ */
7
+ export declare function animationControls(): AnimationControls;
8
+ export declare function setValues(state: MotionState, definition: Options['animate']): void;
@@ -0,0 +1,8 @@
1
+ import { AnimationPlaybackControls } from 'framer-motion';
2
+ import { Ref, UnwrapRef } from 'vue';
3
+ import { createScopedAnimate } from 'framer-motion/dom';
4
+ type Scope = Ref<UnwrapRef<Element>> & {
5
+ animations: AnimationPlaybackControls[];
6
+ };
7
+ export declare function useAnimate<T extends Element = any>(): [Scope, ReturnType<typeof createScopedAnimate>];
8
+ export {};
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Creates `AnimationControls`, which can be used to manually start, stop
3
+ * and sequence animations on one or more components.
4
+ *
5
+ * The returned `AnimationControls` should be passed to the `animate` property
6
+ * of the components you want to animate.
7
+ *
8
+ * These components can then be animated with the `start` method.
9
+ *
10
+ * ```jsx
11
+ * import { motion, useAnimationControls } from 'motion-v'
12
+ *
13
+ * export default defineComponent({
14
+ * setup() {
15
+ * const controls = useAnimationControls()
16
+ *
17
+ * controls.start({
18
+ * x: 100,
19
+ * transition: { duration: 0.5 },
20
+ * })
21
+ *
22
+ * return () => (
23
+ * <motion.div animate={controls} />
24
+ * )
25
+ * }
26
+ * })
27
+ * ```
28
+ *
29
+ * @returns Animation controller with `start`, `stop`, `set` and `mount` methods
30
+ *
31
+ * @public
32
+ */
33
+ export declare function useAnimationControls(): import('../types').AnimationControls;
@@ -1 +1,2 @@
1
- export * from './use-animate';
1
+ export * from './hooks/use-animate';
2
+ export * from './hooks/use-animation-controls';
@@ -0,0 +1,68 @@
1
+ import { MotionState } from '../state';
2
+ import { $Transition, Options } from '../types';
3
+ /**
4
+ * @public
5
+ */
6
+ export interface AnimationControls {
7
+ /**
8
+ * Subscribes a component's animation controls to this.
9
+ *
10
+ * @param controls - The controls to subscribe
11
+ * @returns An unsubscribe function.
12
+ *
13
+ * @internal
14
+ */
15
+ subscribe: (state: MotionState) => () => void;
16
+ /**
17
+ * Starts an animation on all linked components.
18
+ *
19
+ * @remarks
20
+ *
21
+ * ```jsx
22
+ * controls.start("variantLabel")
23
+ * controls.start({
24
+ * x: 0,
25
+ * transition: { duration: 1 }
26
+ * })
27
+ * ```
28
+ *
29
+ * @param definition - Properties or variant label to animate to
30
+ * @param transition - Optional `transtion` to apply to a variant
31
+ * @returns - A `Promise` that resolves when all animations have completed.
32
+ *
33
+ * @public
34
+ */
35
+ start: (definition: Options['animate'], transitionOverride?: $Transition) => Promise<any>;
36
+ /**
37
+ * Instantly set to a set of properties or a variant.
38
+ *
39
+ * ```jsx
40
+ * // With properties
41
+ * controls.set({ opacity: 0 })
42
+ *
43
+ * // With variants
44
+ * controls.set("hidden")
45
+ * ```
46
+ *
47
+ * @privateRemarks
48
+ * We could perform a similar trick to `.start` where this can be called before mount
49
+ * and we maintain a list of of pending actions that get applied on mount. But the
50
+ * expectation of `set` is that it happens synchronously and this would be difficult
51
+ * to do before any children have even attached themselves. It's also poor practise
52
+ * and we should discourage render-synchronous `.start` calls rather than lean into this.
53
+ *
54
+ * @public
55
+ */
56
+ set: (definition: Options['animate']) => void;
57
+ /**
58
+ * Stops animations on all linked components.
59
+ *
60
+ * ```jsx
61
+ * controls.stop()
62
+ * ```
63
+ *
64
+ * @public
65
+ */
66
+ stop: () => void;
67
+ mount: () => () => void;
68
+ }
@@ -0,0 +1,2 @@
1
+ import { AnimationControls } from './types';
2
+ export declare function isAnimationControls(v?: unknown): v is AnimationControls;
@@ -1 +0,0 @@
1
- export declare function requestIdleCallback(callback: () => void): void;
@@ -1,3 +1,3 @@
1
- export { Motion, motion } from './motion';
1
+ export { Motion, motion, type MotionProps } from './motion';
2
2
  export * from './animate-presence';
3
3
  export * from './motion-config';
@@ -1,10 +1,10 @@
1
1
  import { DefineComponent, ExtractPropTypes, ExtractPublicPropTypes, IntrinsicElementAttributes } from 'vue';
2
2
  import { MotionProps } from './Motion';
3
3
  type ComponentProps<T> = T extends DefineComponent<ExtractPropTypes<infer Props>, any, any> ? ExtractPublicPropTypes<Props> : never;
4
- type MotionComponentProps = IntrinsicElementAttributes & {
4
+ type MotionComponentProps = {
5
5
  create: <T extends DefineComponent>(T: any) => DefineComponent<MotionProps<any, unknown> & ComponentProps<T>>;
6
6
  };
7
- interface MotionNameSpace extends Record<keyof IntrinsicElementAttributes, DefineComponent<MotionProps<keyof IntrinsicElementAttributes, unknown> & MotionComponentProps[keyof IntrinsicElementAttributes]>> {
7
+ interface MotionNameSpace extends Record<keyof IntrinsicElementAttributes, DefineComponent<MotionProps<keyof IntrinsicElementAttributes, unknown>>> {
8
8
  create: MotionComponentProps['create'];
9
9
  }
10
10
  export declare const motion: MotionNameSpace;
@@ -0,0 +1,13 @@
1
+ import { Feature } from '../feature';
2
+ import { MotionState } from '../../state';
3
+ export declare class AnimationFeature extends Feature {
4
+ unmountControls?: () => void;
5
+ constructor(state: MotionState);
6
+ updateAnimationControlsSubscription(): void;
7
+ /**
8
+ * Subscribe any provided AnimationControls to the component's VisualElement
9
+ */
10
+ mount(): void;
11
+ update(): void;
12
+ unmount(): void;
13
+ }
@@ -0,0 +1,7 @@
1
+ import { Feature } from '../../feature';
2
+ export declare class FocusGesture extends Feature {
3
+ private isActive;
4
+ onFocus(): void;
5
+ onBlur(): void;
6
+ mount(): void;
7
+ }
@@ -0,0 +1,6 @@
1
+ import { Variant } from '../../../types';
2
+ export type FocusProps = {
3
+ focus?: string | Variant;
4
+ onFocus?: (e: FocusEvent) => void;
5
+ onBlur?: (e: FocusEvent) => void;
6
+ };
@@ -4,3 +4,4 @@ export * from './svg';
4
4
  export * from './layout/layout';
5
5
  export * from './gestures/pan';
6
6
  export * from './feature-manager';
7
+ export * from './animation/animation';
@@ -0,0 +1,19 @@
1
+ import { $Transition, Options } from '../types';
2
+ import { MotionState } from './motion-state';
3
+ declare const STATE_TYPES: readonly ["initial", "animate", "inView", "hover", "press", "whileDrag", "focus", "exit"];
4
+ export type StateType = typeof STATE_TYPES[number];
5
+ /**
6
+ * 核心动画更新函数,处理所有动画状态变化和执行
7
+ * @param controlActiveState - 需要更新的动画状态
8
+ * @param controlDelay - 动画延迟时间
9
+ * @param directAnimate - 直接动画目标值
10
+ * @param directTransition - 直接动画过渡配置
11
+ */
12
+ export declare function animateUpdates(this: MotionState, { controlActiveState, controlDelay, directAnimate, directTransition, isFallback, }?: {
13
+ controlActiveState?: Partial<Record<string, boolean>>;
14
+ controlDelay?: number;
15
+ directAnimate?: Options['animate'];
16
+ directTransition?: $Transition;
17
+ isFallback?: boolean;
18
+ }): any;
19
+ export {};
File without changes
@@ -1,7 +1,6 @@
1
1
  import { MotionStateContext, Options } from '../types';
2
2
  import { DOMKeyframesDefinition, VisualElement } from 'framer-motion';
3
- declare const STATE_TYPES: readonly ["initial", "animate", "inView", "hover", "press", "whileDrag", "exit"];
4
- type StateType = typeof STATE_TYPES[number];
3
+ import { StateType, animateUpdates } from './animate-updates';
5
4
  export declare const mountedStates: WeakMap<Element, MotionState>;
6
5
  /**
7
6
  * Core class that manages animation state and orchestrates animations
@@ -33,9 +32,8 @@ export declare class MotionState {
33
32
  beforeUpdate(): void;
34
33
  update(options: Options, notAnimate?: boolean): void;
35
34
  setActive(name: StateType, isActive: boolean, isAnimate?: boolean): void;
36
- animateUpdates(controlActiveState?: typeof this.activeStates, controlDelay?: number): () => Promise<any>;
35
+ animateUpdates: typeof animateUpdates;
37
36
  isMounted(): boolean;
38
37
  getOptions(): Options<any>;
39
38
  willUpdate(label: string): void;
40
39
  }
41
- export {};
@@ -1,7 +1,7 @@
1
1
  import { $Transition, Options } from '../types';
2
2
  import { Variant } from 'framer-motion';
3
3
  import { IntrinsicElementAttributes } from 'vue';
4
- export declare function resolveVariant(definition?: Options['initial'], variants?: Options['variants'], custom?: Options['custom']): Variant | undefined;
4
+ export declare function resolveVariant(definition?: Options['animate'], variants?: Options['variants'], custom?: Options['custom']): Variant | undefined;
5
5
  export declare function hasChanged(a: any, b: any): boolean;
6
6
  export declare function shallowCompare(next: any[], prev: any[]): boolean;
7
7
  export declare function addUniqueItem<T>(array: T[], item: T): void;