motion-v 0.6.2 → 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 (59) hide show
  1. package/dist/cjs/index.js +408 -221
  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 +5 -1
  7. package/dist/es/components/{Motion.vue.mjs → motion/Motion.vue.mjs} +11 -8
  8. package/dist/es/components/motion/NameSpace.mjs +47 -0
  9. package/dist/es/constants/index.mjs +2 -1
  10. package/dist/es/features/animation/animation.mjs +33 -0
  11. package/dist/es/features/feature-manager.mjs +5 -1
  12. package/dist/es/features/gestures/drag/use-drag-controls.mjs +43 -0
  13. package/dist/es/features/gestures/focus/index.mjs +36 -0
  14. package/dist/es/features/gestures/in-view/index.mjs +25 -5
  15. package/dist/es/features/layout/projection.mjs +7 -30
  16. package/dist/es/index.mjs +11 -5
  17. package/dist/es/state/animate-updates.mjs +129 -0
  18. package/dist/es/state/motion-state.mjs +19 -120
  19. package/dist/es/state/style.mjs +2 -2
  20. package/dist/es/state/transform.mjs +1 -0
  21. package/dist/src/animation/hooks/animation-controls.d.ts +8 -0
  22. package/dist/src/animation/hooks/use-animate.d.ts +8 -0
  23. package/dist/src/animation/hooks/use-animation-controls.d.ts +33 -0
  24. package/dist/src/animation/index.d.ts +2 -1
  25. package/dist/src/animation/types.d.ts +68 -0
  26. package/dist/src/animation/utils.d.ts +2 -0
  27. package/dist/src/components/index.d.ts +1 -0
  28. package/dist/src/components/{Motion.d.ts → motion/Motion.d.ts} +1 -1
  29. package/dist/src/components/motion/NameSpace.d.ts +11 -0
  30. package/dist/src/components/motion/index.d.ts +2 -0
  31. package/dist/src/features/animation/animation.d.ts +13 -0
  32. package/dist/src/features/gestures/drag/VisualElementDragControls.d.ts +1 -1
  33. package/dist/src/features/gestures/focus/index.d.ts +7 -0
  34. package/dist/src/features/gestures/focus/types.d.ts +6 -0
  35. package/dist/src/features/gestures/in-view/index.d.ts +2 -0
  36. package/dist/src/features/index.d.ts +1 -0
  37. package/dist/src/features/layout/projection.d.ts +1 -0
  38. package/dist/src/index.d.ts +1 -1
  39. package/dist/src/state/animate-updates.d.ts +19 -0
  40. package/dist/src/state/animate-variants-children.d.ts +2 -2
  41. package/dist/src/state/animation/index.d.ts +0 -0
  42. package/dist/src/state/animation/types.d.ts +0 -0
  43. package/dist/src/state/motion-state.d.ts +5 -4
  44. package/dist/src/state/utils.d.ts +4 -4
  45. package/dist/src/types/framer-motion.d.ts +17 -0
  46. package/dist/src/types/state.d.ts +10 -16
  47. package/package.json +3 -3
  48. package/dist/es/external/.pnpm/@vueuse_shared@12.0.0_typescript@5.7.2/external/@vueuse/shared/index.mjs +0 -6
  49. package/dist/es/state/animate-variants-children.mjs +0 -74
  50. /package/dist/es/components/{Motion.vue2.mjs → motion/Motion.vue2.mjs} +0 -0
  51. /package/dist/es/components/{Primitive.mjs → motion/Primitive.mjs} +0 -0
  52. /package/dist/es/components/{Slot.mjs → motion/Slot.mjs} +0 -0
  53. /package/dist/es/components/{renderSlotFragments.mjs → motion/renderSlotFragments.mjs} +0 -0
  54. /package/dist/es/components/{utils.mjs → motion/utils.mjs} +0 -0
  55. /package/dist/src/{animation/use-animation.d.ts → components/animate-presence/utils.d.ts} +0 -0
  56. /package/dist/src/components/{Primitive.d.ts → motion/Primitive.d.ts} +0 -0
  57. /package/dist/src/components/{Slot.d.ts → motion/Slot.d.ts} +0 -0
  58. /package/dist/src/components/{renderSlotFragments.d.ts → motion/renderSlotFragments.d.ts} +0 -0
  59. /package/dist/src/components/{utils.d.ts → motion/utils.d.ts} +0 -0
package/dist/cjs/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
3
  const vue = require("vue");
4
+ const core = require("@vueuse/core");
4
5
  const heyListen = require("hey-listen");
5
6
  const noop = (any) => any;
6
7
  let warning = noop;
@@ -3308,7 +3309,7 @@ function initPrefersReducedMotion() {
3308
3309
  }
3309
3310
  const valueTypes = [...dimensionValueTypes, color, complex];
3310
3311
  const findValueType = (v) => valueTypes.find(testValueType(v));
3311
- function isAnimationControls(v) {
3312
+ function isAnimationControls$1(v) {
3312
3313
  return v !== null && typeof v === "object" && typeof v.start === "function";
3313
3314
  }
3314
3315
  function isVariantLabel(v) {
@@ -3325,7 +3326,7 @@ const variantPriorityOrder = [
3325
3326
  ];
3326
3327
  const variantProps = ["initial", ...variantPriorityOrder];
3327
3328
  function isControllingVariants(props) {
3328
- return isAnimationControls(props.animate) || variantProps.some((name) => isVariantLabel(props[name]));
3329
+ return isAnimationControls$1(props.animate) || variantProps.some((name) => isVariantLabel(props[name]));
3329
3330
  }
3330
3331
  function isVariantNode(props) {
3331
3332
  return Boolean(isControllingVariants(props) || props.variants);
@@ -5081,8 +5082,6 @@ const svgElementSet = new Set(svgElements);
5081
5082
  function isSVGElement$1(as) {
5082
5083
  return svgElementSet.has(as);
5083
5084
  }
5084
- typeof WorkerGlobalScope !== "undefined" && globalThis instanceof WorkerGlobalScope;
5085
- const isDef = (val) => typeof val !== "undefined";
5086
5085
  const rotation = {
5087
5086
  syntax: "<angle>",
5088
5087
  initialValue: "0deg",
@@ -5433,20 +5432,40 @@ class InViewGesture extends Feature {
5433
5432
  constructor(state2) {
5434
5433
  super(state2);
5435
5434
  }
5436
- mount() {
5435
+ startObserver() {
5437
5436
  const element = this.state.element;
5438
5437
  if (!element)
5439
5438
  return;
5439
+ this.unmount();
5440
+ const { once, ...viewOptions } = this.state.getOptions().inViewOptions || {};
5440
5441
  this.unmount = inView(
5441
5442
  element,
5442
5443
  (entry) => {
5443
5444
  handleHoverEvent(this.state, entry, "Enter");
5444
- return (endEvent) => {
5445
- handleHoverEvent(this.state, entry, "Leave");
5446
- };
5447
- }
5445
+ if (!once) {
5446
+ return (endEvent) => {
5447
+ handleHoverEvent(this.state, entry, "Leave");
5448
+ };
5449
+ }
5450
+ },
5451
+ viewOptions
5448
5452
  );
5449
5453
  }
5454
+ mount() {
5455
+ this.startObserver();
5456
+ }
5457
+ update() {
5458
+ const { props, prevProps } = this.state.visualElement;
5459
+ const hasOptionsChanged = ["amount", "margin", "root"].some(
5460
+ hasViewportOptionChanged(props, prevProps)
5461
+ );
5462
+ if (hasOptionsChanged) {
5463
+ this.startObserver();
5464
+ }
5465
+ }
5466
+ }
5467
+ function hasViewportOptionChanged({ inViewOptions = {} }, { inViewOptions: prevViewport = {} } = {}) {
5468
+ return (name) => inViewOptions[name] !== prevViewport[name];
5450
5469
  }
5451
5470
  function isPrimaryPointer(event) {
5452
5471
  if (event.pointerType === "mouse") {
@@ -7897,43 +7916,17 @@ class ProjectionFeature extends Feature {
7897
7916
  options["data-framer-portal-id"] ? void 0 : getClosestProjectingNode(this.state.visualElement.parent)
7898
7917
  );
7899
7918
  this.state.visualElement.projection.isPresent = true;
7900
- this.state.visualElement.projection.setOptions({
7901
- layout: options.layout,
7902
- layoutId: options.layoutId,
7903
- // TODO: drag
7904
- alwaysMeasureLayout: false,
7905
- visualElement: this.state.visualElement,
7906
- animationType: typeof options.layout === "string" ? options.layout : "both",
7907
- // initialPromotionConfig
7908
- layoutRoot: options.layoutRoot,
7909
- layoutScroll: options.layoutScroll,
7910
- crossfade: options.crossfade,
7911
- onExitComplete: () => {
7912
- var _a;
7913
- if (!((_a = this.state.visualElement.projection) == null ? void 0 : _a.isPresent)) {
7914
- const done = doneCallbacks.get(this.state.element);
7915
- this.state.isSafeToRemove = true;
7916
- if (done) {
7917
- done({
7918
- detail: {
7919
- isExit: true
7920
- }
7921
- }, true);
7922
- }
7923
- }
7924
- }
7925
- });
7919
+ this.setOptions();
7926
7920
  }
7927
7921
  beforeMount() {
7928
7922
  this.initProjection();
7929
7923
  }
7930
- update() {
7924
+ setOptions() {
7931
7925
  const options = this.state.options;
7932
7926
  this.state.visualElement.projection.setOptions({
7933
7927
  layout: options.layout,
7934
7928
  layoutId: options.layoutId,
7935
- // TODO: drag
7936
- alwaysMeasureLayout: false,
7929
+ alwaysMeasureLayout: Boolean(options.drag) || options.dragConstraints && isHTMLElement(options.dragConstraints),
7937
7930
  visualElement: this.state.visualElement,
7938
7931
  animationType: typeof options.layout === "string" ? options.layout : "both",
7939
7932
  // initialPromotionConfig
@@ -7942,11 +7935,44 @@ class ProjectionFeature extends Feature {
7942
7935
  crossfade: options.crossfade
7943
7936
  });
7944
7937
  }
7938
+ update() {
7939
+ this.setOptions();
7940
+ }
7945
7941
  mount() {
7946
7942
  var _a;
7947
7943
  (_a = this.state.visualElement.projection) == null ? void 0 : _a.mount(this.state.element);
7948
7944
  }
7949
7945
  }
7946
+ class FocusGesture extends Feature {
7947
+ constructor() {
7948
+ super(...arguments);
7949
+ this.isActive = false;
7950
+ }
7951
+ onFocus() {
7952
+ let isFocusVisible = false;
7953
+ try {
7954
+ isFocusVisible = this.state.element.matches(":focus-visible");
7955
+ } catch (e) {
7956
+ isFocusVisible = true;
7957
+ }
7958
+ if (!isFocusVisible)
7959
+ return;
7960
+ this.state.setActive("focus", true);
7961
+ this.isActive = true;
7962
+ }
7963
+ onBlur() {
7964
+ if (!this.isActive)
7965
+ return;
7966
+ this.state.setActive("focus", false);
7967
+ this.isActive = false;
7968
+ }
7969
+ mount() {
7970
+ this.unmount = pipe(
7971
+ addDomEvent$1(this.state.element, "focus", () => this.onFocus()),
7972
+ addDomEvent$1(this.state.element, "blur", () => this.onBlur())
7973
+ );
7974
+ }
7975
+ }
7950
7976
  class FeatureManager {
7951
7977
  constructor(state2) {
7952
7978
  this.features = [];
@@ -7958,7 +7984,9 @@ class FeatureManager {
7958
7984
  new LayoutFeature(state2),
7959
7985
  new ProjectionFeature(state2),
7960
7986
  new PanGesture(state2),
7961
- new DragGesture(state2)
7987
+ new DragGesture(state2),
7988
+ new FocusGesture(state2),
7989
+ new AnimationFeature(state2)
7962
7990
  ];
7963
7991
  }
7964
7992
  mount() {
@@ -7986,80 +8014,160 @@ class FeatureManager {
7986
8014
  this.features.forEach((feature) => feature.beforeUnmount());
7987
8015
  }
7988
8016
  }
7989
- function motionEvent(name, target, isExit) {
7990
- return new CustomEvent(name, { detail: { target, isExit } });
8017
+ function isAnimationControls(v) {
8018
+ return v !== null && typeof v === "object" && typeof v.start === "function";
8019
+ }
8020
+ class AnimationFeature extends Feature {
8021
+ constructor(state2) {
8022
+ super(state2);
8023
+ }
8024
+ updateAnimationControlsSubscription() {
8025
+ const { animate: animate2 } = this.state.options;
8026
+ if (isAnimationControls(animate2)) {
8027
+ this.unmountControls = animate2.subscribe(this.state);
8028
+ }
8029
+ }
8030
+ /**
8031
+ * Subscribe any provided AnimationControls to the component's VisualElement
8032
+ */
8033
+ mount() {
8034
+ this.updateAnimationControlsSubscription();
8035
+ }
8036
+ update() {
8037
+ const { animate: animate2 } = this.state.options;
8038
+ const { animate: prevAnimate } = this.state.visualElement.prevProps || {};
8039
+ if (animate2 !== prevAnimate) {
8040
+ this.updateAnimationControlsSubscription();
8041
+ }
8042
+ }
8043
+ unmount() {
8044
+ var _a;
8045
+ (_a = this.unmountControls) == null ? void 0 : _a.call(this);
8046
+ }
7991
8047
  }
7992
8048
  function createVisualElement(Component, options) {
7993
8049
  return isSVGElement$1(Component) ? new SVGVisualElement(options) : new HTMLVisualElement(options);
7994
8050
  }
7995
- function animateVariantsChildren(state2, activeState, isFirstAnimate = false) {
7996
- const variantChildren = state2.visualElement.variantChildren;
7997
- if (!(variantChildren == null ? void 0 : variantChildren.size)) {
7998
- return {
7999
- animations: [],
8000
- getAnimations: () => Promise.resolve()
8001
- };
8002
- }
8003
- const animationFactories = [];
8004
- Array.from(variantChildren).forEach((child, index) => {
8051
+ function motionEvent(name, target, isExit) {
8052
+ return new CustomEvent(name, { detail: { target, isExit } });
8053
+ }
8054
+ const STATE_TYPES = ["initial", "animate", "inView", "hover", "press", "whileDrag", "focus", "exit"];
8055
+ function animateUpdates({
8056
+ controlActiveState = void 0,
8057
+ controlDelay = 0,
8058
+ directAnimate,
8059
+ directTransition,
8060
+ isFallback = false
8061
+ } = {}) {
8062
+ const prevTarget = this.target;
8063
+ this.target = { ...this.baseTarget };
8064
+ const animationOptions = {};
8065
+ const transition = { ...this.options.transition };
8066
+ if (directAnimate)
8067
+ resolveDirectAnimation.call(this, directAnimate, directTransition, animationOptions);
8068
+ else
8069
+ resolveStateAnimation.call(this, controlActiveState, animationOptions);
8070
+ const factories = createAnimationFactories.call(this, prevTarget, animationOptions, controlDelay);
8071
+ const { getChildAnimations, childAnimations } = setupChildAnimations.call(this, transition, controlActiveState, isFallback);
8072
+ return executeAnimations.call(this, factories, getChildAnimations, childAnimations, transition, controlActiveState);
8073
+ }
8074
+ function resolveDirectAnimation(directAnimate, directTransition, animationOptions) {
8075
+ const variant = resolveVariant(directAnimate, this.options.variants, this.options.custom);
8076
+ if (!variant)
8077
+ return;
8078
+ const transition = { ...this.options.transition, ...directTransition || variant.transition };
8079
+ Object.entries(variant).forEach(([key, value]) => {
8080
+ if (key === "transition")
8081
+ return;
8082
+ this.target[key] = value;
8083
+ animationOptions[key] = getOptions(transition, key);
8084
+ });
8085
+ }
8086
+ function resolveStateAnimation(controlActiveState, animationOptions) {
8087
+ if (controlActiveState)
8088
+ this.activeStates = { ...this.activeStates, ...controlActiveState };
8089
+ STATE_TYPES.forEach((name) => {
8090
+ if (!this.activeStates[name] || isAnimationControls(this.options[name]))
8091
+ return;
8092
+ const definition = core.isDef(this.options[name]) ? this.options[name] : this.context[name];
8093
+ const variant = resolveVariant(definition, this.options.variants, this.options.custom);
8094
+ if (!variant)
8095
+ return;
8096
+ const transition = { ...this.options.transition, ...variant.transition };
8097
+ Object.entries(variant).forEach(([key, value]) => {
8098
+ if (key === "transition")
8099
+ return;
8100
+ this.target[key] = value;
8101
+ animationOptions[key] = getOptions(transition, key);
8102
+ });
8103
+ });
8104
+ }
8105
+ function createAnimationFactories(prevTarget, animationOptions, controlDelay) {
8106
+ const factories = [];
8107
+ new Set(Object.keys(this.target)).forEach((key) => {
8005
8108
  var _a;
8006
- const prevTarget = isFirstAnimate ? child.state.baseTarget : child.state.target;
8007
- const childState = child.state;
8008
- childState.target = {};
8009
- for (const name in activeState) {
8010
- if (name === "initial" && !isFirstAnimate) {
8011
- continue;
8012
- }
8013
- const { definition, transition } = activeState[name];
8014
- const { staggerChildren = 0, staggerDirection = 1, delayChildren = 0 } = transition || {};
8015
- const maxStaggerDuration = (variantChildren.size - 1) * staggerChildren;
8016
- const generateStaggerDuration = staggerDirection === 1 ? (i = 0) => i * staggerChildren : (i = 0) => maxStaggerDuration - i * staggerChildren;
8017
- const variant = resolveVariant(
8018
- definition,
8019
- child.props.variants,
8020
- child.props.custom
8021
- );
8022
- const animationOptions = {};
8023
- const allTarget = { ...prevTarget, ...variant };
8024
- for (const key in allTarget) {
8025
- if (key === "transition")
8026
- continue;
8027
- childState.target[key] = allTarget[key];
8028
- if (childState.target[key] === void 0) {
8029
- childState.target[key] = childState.baseTarget[key];
8030
- }
8031
- if (hasChanged(prevTarget[key], childState.target[key])) {
8032
- (_a = childState.baseTarget)[key] ?? (_a[key] = style.get(child.current, key));
8033
- animationOptions[key] = getOptions(
8034
- Object.assign({}, transition, allTarget.transition, child.props.transition),
8035
- key
8036
- );
8037
- const keyValue = childState.target[key] === "none" ? transformResetValue[key] : childState.target[key];
8038
- animationFactories.push(
8039
- () => {
8040
- var _a2;
8041
- return animate(
8042
- child.current,
8043
- {
8044
- [key]: keyValue
8045
- },
8046
- {
8047
- ...animationOptions[key] || {},
8048
- delay: (((_a2 = animationOptions[key]) == null ? void 0 : _a2.delay) || 0) + delayChildren + generateStaggerDuration(index)
8049
- }
8050
- );
8051
- }
8052
- );
8053
- }
8109
+ if (!hasChanged(this.visualElement.getValue(key), this.target[key]))
8110
+ return;
8111
+ (_a = this.baseTarget)[key] ?? (_a[key] = style.get(this.element, key));
8112
+ const keyValue = this.target[key] === "none" ? transformResetValue[key] : this.target[key];
8113
+ const targetTransition = animationOptions[key];
8114
+ factories.push(() => animate(
8115
+ this.element,
8116
+ { [key]: keyValue },
8117
+ {
8118
+ ...targetTransition,
8119
+ delay: ((targetTransition == null ? void 0 : targetTransition.delay) || 0) + controlDelay
8054
8120
  }
8055
- }
8121
+ ));
8056
8122
  });
8123
+ return factories;
8124
+ }
8125
+ function setupChildAnimations(transition, controlActiveState, isFallback) {
8126
+ var _a;
8127
+ if (!((_a = this.visualElement.variantChildren) == null ? void 0 : _a.size) || controlActiveState)
8128
+ return { getChildAnimations: () => Promise.resolve(), childAnimations: [] };
8129
+ const { staggerChildren = 0, staggerDirection = 1, delayChildren = 0 } = transition || {};
8130
+ const maxStaggerDuration = (this.visualElement.variantChildren.size - 1) * staggerChildren;
8131
+ const generateStaggerDuration = staggerDirection === 1 ? (i = 0) => i * staggerChildren : (i = 0) => maxStaggerDuration - i * staggerChildren;
8132
+ const childAnimations = Array.from(this.visualElement.variantChildren).map((child, index) => {
8133
+ const childDelay = delayChildren + generateStaggerDuration(index);
8134
+ return child.state.animateUpdates({
8135
+ controlActiveState: this.activeStates,
8136
+ controlDelay: isFallback ? 0 : childDelay
8137
+ });
8138
+ }).filter(Boolean);
8057
8139
  return {
8058
- animations: animationFactories,
8059
- getAnimations: () => Promise.all(animationFactories.map((factory) => factory()))
8140
+ getChildAnimations: () => Promise.all(childAnimations.map((animation) => animation())),
8141
+ childAnimations
8142
+ };
8143
+ }
8144
+ function executeAnimations(factories, getChildAnimations, childAnimations, transition, controlActiveState) {
8145
+ let animations;
8146
+ const getAnimation = () => {
8147
+ animations = factories.map((factory) => factory()).filter(Boolean);
8148
+ return Promise.all(animations);
8060
8149
  };
8150
+ const isExit = this.activeStates.exit;
8151
+ const animationTarget2 = { ...this.target };
8152
+ const element = this.element;
8153
+ const finishAnimation2 = (animationPromise) => {
8154
+ if (!(animations == null ? void 0 : animations.length) && !childAnimations.length) {
8155
+ if (isExit) {
8156
+ element.dispatchEvent(motionEvent("motionstart", animationTarget2));
8157
+ element.dispatchEvent(motionEvent("motioncomplete", animationTarget2, isExit));
8158
+ }
8159
+ return;
8160
+ }
8161
+ element.dispatchEvent(motionEvent("motionstart", animationTarget2));
8162
+ animationPromise.then(() => element.dispatchEvent(motionEvent("motioncomplete", animationTarget2, isExit))).catch(noop);
8163
+ };
8164
+ const getAnimationPromise = () => {
8165
+ const animationPromise = (transition == null ? void 0 : transition.when) ? (transition.when === "beforeChildren" ? getAnimation() : getChildAnimations()).then(() => transition.when === "beforeChildren" ? getChildAnimations() : getAnimation()) : Promise.all([getAnimation(), getChildAnimations()]);
8166
+ finishAnimation2(animationPromise);
8167
+ return animationPromise;
8168
+ };
8169
+ return controlActiveState ? getAnimationPromise : getAnimationPromise();
8061
8170
  }
8062
- const STATE_TYPES = ["initial", "animate", "inView", "hover", "press", "whileDrag", "exit"];
8063
8171
  const mountedStates = /* @__PURE__ */ new WeakMap();
8064
8172
  let id = 0;
8065
8173
  class MotionState {
@@ -8070,10 +8178,11 @@ class MotionState {
8070
8178
  this.isVShow = false;
8071
8179
  this.children = /* @__PURE__ */ new Set();
8072
8180
  this.activeStates = {
8073
- // initial: true,
8181
+ initial: true,
8074
8182
  animate: true
8075
8183
  };
8076
8184
  this._context = null;
8185
+ this.animateUpdates = animateUpdates;
8077
8186
  this.id = `motion-state-${id++}`;
8078
8187
  this.options = options;
8079
8188
  this.parent = parent;
@@ -8104,6 +8213,7 @@ class MotionState {
8104
8213
  this.initTarget(initialVariantSource);
8105
8214
  this.featureManager = new FeatureManager(this);
8106
8215
  }
8216
+ // Get animation context, falling back to parent context
8107
8217
  get context() {
8108
8218
  if (!this._context) {
8109
8219
  const handler = {
@@ -8116,13 +8226,16 @@ class MotionState {
8116
8226
  }
8117
8227
  return this._context;
8118
8228
  }
8229
+ // Initialize animation target values
8119
8230
  initTarget(initialVariantSource) {
8120
8231
  this.baseTarget = resolveVariant(this.options[initialVariantSource] || this.context[initialVariantSource], this.options.variants) || {};
8121
8232
  this.target = {};
8122
8233
  }
8234
+ // Get initial animation state
8123
8235
  get initial() {
8124
- return isDef(this.options.initial) ? this.options.initial : this.context.initial;
8236
+ return core.isDef(this.options.initial) ? this.options.initial : this.context.initial;
8125
8237
  }
8238
+ // Update visual element with new options
8126
8239
  updateOptions() {
8127
8240
  this.visualElement.update({
8128
8241
  ...this.options,
@@ -8137,6 +8250,7 @@ class MotionState {
8137
8250
  beforeMount() {
8138
8251
  this.featureManager.beforeMount();
8139
8252
  }
8253
+ // Mount motion state to DOM element
8140
8254
  mount(element, options, notAnimate = false) {
8141
8255
  heyListen.invariant(
8142
8256
  Boolean(element),
@@ -8161,13 +8275,14 @@ class MotionState {
8161
8275
  }
8162
8276
  }
8163
8277
  this.featureManager.mount();
8164
- if (!notAnimate) {
8165
- this.animateUpdates(true);
8278
+ if (!notAnimate && this.options.animate) {
8279
+ this.animateUpdates();
8166
8280
  }
8167
8281
  }
8168
8282
  beforeUnmount() {
8169
8283
  this.featureManager.beforeUnmount();
8170
8284
  }
8285
+ // Unmount motion state and optionally unmount children
8171
8286
  unmount(unMountChildren = false) {
8172
8287
  var _a, _b, _c;
8173
8288
  mountedStates.delete(this.element);
@@ -8193,6 +8308,7 @@ class MotionState {
8193
8308
  beforeUpdate() {
8194
8309
  this.featureManager.beforeUpdate();
8195
8310
  }
8311
+ // Update motion state with new options
8196
8312
  update(options, notAnimate = false) {
8197
8313
  const prevAnimate = JSON.stringify(this.options.animate);
8198
8314
  this.options = options;
@@ -8206,122 +8322,20 @@ class MotionState {
8206
8322
  this.animateUpdates();
8207
8323
  }
8208
8324
  }
8325
+ // Set animation state active status
8209
8326
  setActive(name, isActive, isAnimate = true) {
8210
8327
  var _a;
8211
8328
  if (!this.element || this.activeStates[name] === isActive)
8212
8329
  return;
8213
8330
  this.activeStates[name] = isActive;
8214
8331
  (_a = this.visualElement.variantChildren) == null ? void 0 : _a.forEach((child) => {
8215
- child.state.setActive(name, isActive, !isActive);
8332
+ child.state.setActive(name, isActive, false);
8216
8333
  });
8217
8334
  if (isAnimate) {
8218
- this.animateUpdates();
8219
- }
8220
- }
8221
- animateUpdates(isInitial = false) {
8222
- const prevTarget = this.target;
8223
- this.target = {};
8224
- const activeState = {};
8225
- const animationOptions = {};
8226
- let transition;
8227
- for (const name of STATE_TYPES) {
8228
- if (name === "initial") {
8229
- if (!isInitial) {
8230
- continue;
8231
- }
8232
- }
8233
- if (!this.activeStates[name] && name !== "initial") {
8234
- continue;
8235
- }
8236
- const definition = isDef(this.options[name]) ? this.options[name] : this.context[name];
8237
- const variant = resolveVariant(
8238
- definition,
8239
- this.options.variants,
8240
- this.options.custom
8241
- );
8242
- transition = Object.assign({}, this.options.transition, variant == null ? void 0 : variant.transition);
8243
- if (typeof definition === "string") {
8244
- activeState[name] = {
8245
- definition,
8246
- transition
8247
- };
8248
- }
8249
- if (!variant)
8250
- continue;
8251
- const allTarget = { ...prevTarget, ...variant };
8252
- for (const key in allTarget) {
8253
- if (key === "transition")
8254
- continue;
8255
- this.target[key] = variant[key];
8256
- animationOptions[key] = getOptions(
8257
- transition,
8258
- key
8259
- );
8260
- }
8261
- }
8262
- const allTargetKeys = /* @__PURE__ */ new Set([
8263
- ...Object.keys(this.target),
8264
- ...Object.keys(prevTarget)
8265
- ]);
8266
- const animationFactories = [];
8267
- allTargetKeys.forEach((key) => {
8268
- var _a;
8269
- if (this.target[key] === void 0) {
8270
- this.target[key] = this.baseTarget[key];
8271
- }
8272
- if (hasChanged(prevTarget[key], this.target[key])) {
8273
- (_a = this.baseTarget)[key] ?? (_a[key] = style.get(this.element, key));
8274
- const keyValue = this.target[key] === "none" ? transformResetValue[key] : this.target[key];
8275
- animationFactories.push(
8276
- () => {
8277
- return animate(
8278
- this.element,
8279
- {
8280
- [key]: keyValue
8281
- },
8282
- animationOptions[key] || {}
8283
- );
8284
- }
8285
- );
8286
- }
8287
- });
8288
- let getChildAnimations = () => Promise.resolve();
8289
- let childAnimations = [];
8290
- if (Object.keys(activeState).length) {
8291
- const { getAnimations, animations: animations2 } = animateVariantsChildren(this, activeState, isInitial);
8292
- getChildAnimations = getAnimations;
8293
- childAnimations = animations2;
8294
- }
8295
- let animations;
8296
- const getAnimation = () => {
8297
- animations = animationFactories.map((factory) => factory()).filter(Boolean);
8298
- return Promise.all(animations);
8299
- };
8300
- const { when } = transition;
8301
- let animationPromise;
8302
- if (when) {
8303
- const [first, last] = when === "beforeChildren" ? [getAnimation, getChildAnimations] : [getChildAnimations, getAnimation];
8304
- animationPromise = first().then(() => last());
8305
- } else {
8306
- animationPromise = Promise.all([getAnimation(), getChildAnimations()]);
8307
- }
8308
- const isExit = this.activeStates.exit;
8309
- if (!(animations == null ? void 0 : animations.length) && !childAnimations.length) {
8310
- if (isExit) {
8311
- this.element.dispatchEvent(motionEvent("motionstart", this.target));
8312
- this.element.dispatchEvent(motionEvent("motioncomplete", {
8313
- ...this.target
8314
- }, isExit));
8315
- }
8316
- return;
8335
+ this.animateUpdates({
8336
+ isFallback: !isActive
8337
+ });
8317
8338
  }
8318
- const animationTarget2 = this.target;
8319
- this.element.dispatchEvent(motionEvent("motionstart", animationTarget2));
8320
- animationPromise.then(() => {
8321
- this.element.dispatchEvent(motionEvent("motioncomplete", {
8322
- ...animationTarget2
8323
- }, isExit));
8324
- }).catch(noop);
8325
8339
  }
8326
8340
  isMounted() {
8327
8341
  return Boolean(this.element);
@@ -8413,7 +8427,10 @@ const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
8413
8427
  onPanSessionStart: { type: Function },
8414
8428
  onPanStart: { type: Function },
8415
8429
  onPan: { type: Function },
8416
- onPanEnd: { type: Function }
8430
+ onPanEnd: { type: Function },
8431
+ focus: {},
8432
+ onFocus: { type: Function },
8433
+ onBlur: { type: Function }
8417
8434
  }, {
8418
8435
  as: "div",
8419
8436
  asChild: false,
@@ -8426,7 +8443,7 @@ const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
8426
8443
  layoutScroll: false,
8427
8444
  layoutRoot: false,
8428
8445
  dragListener: true,
8429
- dragElastic: 0.2,
8446
+ dragElastic: 0.5,
8430
8447
  dragMomentum: true,
8431
8448
  whileDrag: void 0,
8432
8449
  crossfade: true
@@ -8539,6 +8556,48 @@ const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
8539
8556
  };
8540
8557
  }
8541
8558
  });
8559
+ const componentCache = /* @__PURE__ */ new Map();
8560
+ const motion = new Proxy(_sfc_main$3, {
8561
+ get(target, prop) {
8562
+ if (typeof prop === "symbol")
8563
+ return target[prop];
8564
+ let motionComponent = componentCache.get(prop);
8565
+ if (prop === "create") {
8566
+ return (component) => {
8567
+ return vue.defineComponent({
8568
+ inheritAttrs: false,
8569
+ name: `motion.${component.$name}`,
8570
+ setup(_, { attrs, slots }) {
8571
+ return () => {
8572
+ return vue.h(_sfc_main$3, {
8573
+ ...attrs,
8574
+ as: component,
8575
+ asChild: false
8576
+ }, slots);
8577
+ };
8578
+ }
8579
+ });
8580
+ };
8581
+ }
8582
+ if (!motionComponent) {
8583
+ motionComponent = vue.defineComponent({
8584
+ inheritAttrs: false,
8585
+ name: `motion.${prop}`,
8586
+ setup(_, { attrs, slots }) {
8587
+ return () => {
8588
+ return vue.h(_sfc_main$3, {
8589
+ ...attrs,
8590
+ as: prop,
8591
+ asChild: false
8592
+ }, slots);
8593
+ };
8594
+ }
8595
+ });
8596
+ componentCache.set(prop, motionComponent);
8597
+ }
8598
+ return motionComponent;
8599
+ }
8600
+ });
8542
8601
  function usePopLayout(props) {
8543
8602
  const styles = /* @__PURE__ */ new WeakMap();
8544
8603
  const config = useMotionConfig();
@@ -8650,9 +8709,12 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
8650
8709
  }
8651
8710
  if (!styles.has(state2)) {
8652
8711
  state2.willUpdate("done");
8712
+ } else {
8713
+ frame.render(() => {
8714
+ removePopStyle(state2);
8715
+ });
8653
8716
  }
8654
8717
  done();
8655
- removePopStyle(state2);
8656
8718
  if (!(el == null ? void 0 : el.isConnected)) {
8657
8719
  state2.unmount(true);
8658
8720
  }
@@ -8893,7 +8955,7 @@ function useSpring(source, config = {}) {
8893
8955
  let latestValue = value.get();
8894
8956
  let latestSetter = () => {
8895
8957
  };
8896
- const stopAnimation = () => {
8958
+ const stopAnimation2 = () => {
8897
8959
  if (activeSpringAnimation) {
8898
8960
  activeSpringAnimation.stop();
8899
8961
  activeSpringAnimation = null;
@@ -8904,7 +8966,7 @@ function useSpring(source, config = {}) {
8904
8966
  if ((animation == null ? void 0 : animation.time) === 0) {
8905
8967
  animation.sample(frameData.delta);
8906
8968
  }
8907
- stopAnimation();
8969
+ stopAnimation2();
8908
8970
  activeSpringAnimation = animateValue({
8909
8971
  keyframes: [value.get(), latestValue],
8910
8972
  velocity: value.getVelocity(),
@@ -8921,7 +8983,7 @@ function useSpring(source, config = {}) {
8921
8983
  latestSetter = set;
8922
8984
  frame.update(startAnimation);
8923
8985
  return value.get();
8924
- }, stopAnimation);
8986
+ }, stopAnimation2);
8925
8987
  }, { immediate: true });
8926
8988
  if (isMotionValue(source)) {
8927
8989
  source.on("change", (v) => {
@@ -9014,7 +9076,8 @@ const utilities = {
9014
9076
  "useInView",
9015
9077
  "useAnimationFrame",
9016
9078
  "useMotionValueEvent",
9017
- "useLayoutGroup"
9079
+ "useLayoutGroup",
9080
+ "useDragControls"
9018
9081
  ]
9019
9082
  };
9020
9083
  function useAnimate() {
@@ -9043,6 +9106,127 @@ function useAnimate() {
9043
9106
  });
9044
9107
  return [domProxy, animate2];
9045
9108
  }
9109
+ function stopAnimation(visualElement) {
9110
+ visualElement.values.forEach((value) => value.stop());
9111
+ }
9112
+ function animationControls() {
9113
+ let hasMounted = false;
9114
+ const subscribers = /* @__PURE__ */ new Set();
9115
+ const controls = {
9116
+ subscribe(state2) {
9117
+ subscribers.add(state2);
9118
+ return () => void subscribers.delete(state2);
9119
+ },
9120
+ start(definition, transitionOverride) {
9121
+ heyListen.invariant(
9122
+ hasMounted,
9123
+ "controls.start() should only be called after a component has mounted. Consider calling within a useEffect hook."
9124
+ );
9125
+ const animations = [];
9126
+ subscribers.forEach((state2) => {
9127
+ animations.push(
9128
+ state2.animateUpdates({
9129
+ directAnimate: definition,
9130
+ directTransition: transitionOverride
9131
+ })
9132
+ );
9133
+ });
9134
+ return Promise.all(animations);
9135
+ },
9136
+ set(definition) {
9137
+ heyListen.invariant(
9138
+ hasMounted,
9139
+ "controls.set() should only be called after a component has mounted. Consider calling within a useEffect hook."
9140
+ );
9141
+ return subscribers.forEach((state2) => {
9142
+ setValues(state2, definition);
9143
+ });
9144
+ },
9145
+ stop() {
9146
+ subscribers.forEach((state2) => {
9147
+ stopAnimation(state2.visualElement);
9148
+ });
9149
+ },
9150
+ mount() {
9151
+ hasMounted = true;
9152
+ return () => {
9153
+ hasMounted = false;
9154
+ controls.stop();
9155
+ };
9156
+ }
9157
+ };
9158
+ return controls;
9159
+ }
9160
+ function setValues(state2, definition) {
9161
+ if (typeof definition === "string") {
9162
+ return setVariants(state2, [definition]);
9163
+ } else {
9164
+ setTarget(state2.visualElement, definition);
9165
+ }
9166
+ }
9167
+ function setVariants(state2, variantLabels) {
9168
+ const reversedLabels = [...variantLabels].reverse();
9169
+ const visualElement = state2.visualElement;
9170
+ reversedLabels.forEach((key) => {
9171
+ const variant = visualElement.getVariant(key);
9172
+ variant && setTarget(visualElement, variant);
9173
+ if (visualElement.variantChildren) {
9174
+ visualElement.variantChildren.forEach((child) => {
9175
+ setVariants(mountedStates.get(child.current), variantLabels);
9176
+ });
9177
+ }
9178
+ });
9179
+ }
9180
+ function useAnimationControls() {
9181
+ const controls = animationControls();
9182
+ let unmount;
9183
+ vue.onMounted(() => {
9184
+ unmount = controls.mount();
9185
+ });
9186
+ vue.onUnmounted(() => {
9187
+ unmount();
9188
+ });
9189
+ return controls;
9190
+ }
9191
+ class DragControls {
9192
+ constructor() {
9193
+ this.componentControls = /* @__PURE__ */ new Set();
9194
+ }
9195
+ /**
9196
+ * Subscribe a component's internal `VisualElementDragControls` to the user-facing API.
9197
+ *
9198
+ * @internal
9199
+ */
9200
+ subscribe(controls) {
9201
+ this.componentControls.add(controls);
9202
+ return () => this.componentControls.delete(controls);
9203
+ }
9204
+ /**
9205
+ * Start a drag gesture on every `motion` component that has this set of drag controls
9206
+ * passed into it via the `dragControls` prop.
9207
+ *
9208
+ * ```jsx
9209
+ * dragControls.start(e, {
9210
+ * snapToCursor: true
9211
+ * })
9212
+ * ```
9213
+ *
9214
+ * @param event - PointerEvent
9215
+ * @param options - Options
9216
+ *
9217
+ * @public
9218
+ */
9219
+ start(event, options) {
9220
+ this.componentControls.forEach((controls) => {
9221
+ controls.start(
9222
+ event,
9223
+ options
9224
+ );
9225
+ });
9226
+ }
9227
+ }
9228
+ const createDragControls = () => new DragControls();
9229
+ const useDragControls = createDragControls;
9046
9230
  exports.AnimatePresence = _sfc_main$2;
9047
9231
  exports.LayoutGroup = _sfc_main;
9048
9232
  exports.Motion = _sfc_main$3;
@@ -9085,6 +9269,7 @@ exports.keyframes = keyframes;
9085
9269
  exports.millisecondsToSeconds = millisecondsToSeconds;
9086
9270
  exports.mirrorEasing = mirrorEasing;
9087
9271
  exports.mix = mix;
9272
+ exports.motion = motion;
9088
9273
  exports.motionValue = motionValue;
9089
9274
  exports.noop = noop;
9090
9275
  exports.pipe = pipe;
@@ -9103,9 +9288,11 @@ exports.sync = sync;
9103
9288
  exports.time = time;
9104
9289
  exports.transform = transform;
9105
9290
  exports.useAnimate = useAnimate;
9291
+ exports.useAnimationControls = useAnimationControls;
9106
9292
  exports.useAnimationFrame = useAnimationFrame;
9107
9293
  exports.useCombineMotionValues = useCombineMotionValues;
9108
9294
  exports.useComputed = useComputed;
9295
+ exports.useDragControls = useDragControls;
9109
9296
  exports.useInView = useInView;
9110
9297
  exports.useLayoutGroup = useLayoutGroup;
9111
9298
  exports.useMotionConfig = useMotionConfig;