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.
- package/dist/cjs/index.js +408 -221
- package/dist/es/animation/hooks/animation-controls.mjs +78 -0
- package/dist/es/animation/{use-animate.mjs → hooks/use-animate.mjs} +1 -1
- package/dist/es/animation/hooks/use-animation-controls.mjs +16 -0
- package/dist/es/animation/utils.mjs +6 -0
- package/dist/es/components/animate-presence/AnimatePresence.vue.mjs +5 -1
- package/dist/es/components/{Motion.vue.mjs → motion/Motion.vue.mjs} +11 -8
- package/dist/es/components/motion/NameSpace.mjs +47 -0
- package/dist/es/constants/index.mjs +2 -1
- package/dist/es/features/animation/animation.mjs +33 -0
- package/dist/es/features/feature-manager.mjs +5 -1
- package/dist/es/features/gestures/drag/use-drag-controls.mjs +43 -0
- package/dist/es/features/gestures/focus/index.mjs +36 -0
- package/dist/es/features/gestures/in-view/index.mjs +25 -5
- package/dist/es/features/layout/projection.mjs +7 -30
- package/dist/es/index.mjs +11 -5
- package/dist/es/state/animate-updates.mjs +129 -0
- package/dist/es/state/motion-state.mjs +19 -120
- package/dist/es/state/style.mjs +2 -2
- package/dist/es/state/transform.mjs +1 -0
- package/dist/src/animation/hooks/animation-controls.d.ts +8 -0
- package/dist/src/animation/hooks/use-animate.d.ts +8 -0
- package/dist/src/animation/hooks/use-animation-controls.d.ts +33 -0
- package/dist/src/animation/index.d.ts +2 -1
- package/dist/src/animation/types.d.ts +68 -0
- package/dist/src/animation/utils.d.ts +2 -0
- package/dist/src/components/index.d.ts +1 -0
- package/dist/src/components/{Motion.d.ts → motion/Motion.d.ts} +1 -1
- package/dist/src/components/motion/NameSpace.d.ts +11 -0
- package/dist/src/components/motion/index.d.ts +2 -0
- package/dist/src/features/animation/animation.d.ts +13 -0
- package/dist/src/features/gestures/drag/VisualElementDragControls.d.ts +1 -1
- package/dist/src/features/gestures/focus/index.d.ts +7 -0
- package/dist/src/features/gestures/focus/types.d.ts +6 -0
- package/dist/src/features/gestures/in-view/index.d.ts +2 -0
- package/dist/src/features/index.d.ts +1 -0
- package/dist/src/features/layout/projection.d.ts +1 -0
- package/dist/src/index.d.ts +1 -1
- package/dist/src/state/animate-updates.d.ts +19 -0
- package/dist/src/state/animate-variants-children.d.ts +2 -2
- package/dist/src/state/animation/index.d.ts +0 -0
- package/dist/src/state/animation/types.d.ts +0 -0
- package/dist/src/state/motion-state.d.ts +5 -4
- package/dist/src/state/utils.d.ts +4 -4
- package/dist/src/types/framer-motion.d.ts +17 -0
- package/dist/src/types/state.d.ts +10 -16
- package/package.json +3 -3
- package/dist/es/external/.pnpm/@vueuse_shared@12.0.0_typescript@5.7.2/external/@vueuse/shared/index.mjs +0 -6
- package/dist/es/state/animate-variants-children.mjs +0 -74
- /package/dist/es/components/{Motion.vue2.mjs → motion/Motion.vue2.mjs} +0 -0
- /package/dist/es/components/{Primitive.mjs → motion/Primitive.mjs} +0 -0
- /package/dist/es/components/{Slot.mjs → motion/Slot.mjs} +0 -0
- /package/dist/es/components/{renderSlotFragments.mjs → motion/renderSlotFragments.mjs} +0 -0
- /package/dist/es/components/{utils.mjs → motion/utils.mjs} +0 -0
- /package/dist/src/{animation/use-animation.d.ts → components/animate-presence/utils.d.ts} +0 -0
- /package/dist/src/components/{Primitive.d.ts → motion/Primitive.d.ts} +0 -0
- /package/dist/src/components/{Slot.d.ts → motion/Slot.d.ts} +0 -0
- /package/dist/src/components/{renderSlotFragments.d.ts → motion/renderSlotFragments.d.ts} +0 -0
- /package/dist/src/components/{utils.d.ts → motion/utils.d.ts} +0 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { mountedStates } from "../../state/motion-state.mjs";
|
|
2
|
+
import { invariant } from "hey-listen";
|
|
3
|
+
import { setTarget } from "../../external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/render/utils/setters.mjs";
|
|
4
|
+
function stopAnimation(visualElement) {
|
|
5
|
+
visualElement.values.forEach((value) => value.stop());
|
|
6
|
+
}
|
|
7
|
+
function animationControls() {
|
|
8
|
+
let hasMounted = false;
|
|
9
|
+
const subscribers = /* @__PURE__ */ new Set();
|
|
10
|
+
const controls = {
|
|
11
|
+
subscribe(state) {
|
|
12
|
+
subscribers.add(state);
|
|
13
|
+
return () => void subscribers.delete(state);
|
|
14
|
+
},
|
|
15
|
+
start(definition, transitionOverride) {
|
|
16
|
+
invariant(
|
|
17
|
+
hasMounted,
|
|
18
|
+
"controls.start() should only be called after a component has mounted. Consider calling within a useEffect hook."
|
|
19
|
+
);
|
|
20
|
+
const animations = [];
|
|
21
|
+
subscribers.forEach((state) => {
|
|
22
|
+
animations.push(
|
|
23
|
+
state.animateUpdates({
|
|
24
|
+
directAnimate: definition,
|
|
25
|
+
directTransition: transitionOverride
|
|
26
|
+
})
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
return Promise.all(animations);
|
|
30
|
+
},
|
|
31
|
+
set(definition) {
|
|
32
|
+
invariant(
|
|
33
|
+
hasMounted,
|
|
34
|
+
"controls.set() should only be called after a component has mounted. Consider calling within a useEffect hook."
|
|
35
|
+
);
|
|
36
|
+
return subscribers.forEach((state) => {
|
|
37
|
+
setValues(state, definition);
|
|
38
|
+
});
|
|
39
|
+
},
|
|
40
|
+
stop() {
|
|
41
|
+
subscribers.forEach((state) => {
|
|
42
|
+
stopAnimation(state.visualElement);
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
mount() {
|
|
46
|
+
hasMounted = true;
|
|
47
|
+
return () => {
|
|
48
|
+
hasMounted = false;
|
|
49
|
+
controls.stop();
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
return controls;
|
|
54
|
+
}
|
|
55
|
+
function setValues(state, definition) {
|
|
56
|
+
if (typeof definition === "string") {
|
|
57
|
+
return setVariants(state, [definition]);
|
|
58
|
+
} else {
|
|
59
|
+
setTarget(state.visualElement, definition);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function setVariants(state, variantLabels) {
|
|
63
|
+
const reversedLabels = [...variantLabels].reverse();
|
|
64
|
+
const visualElement = state.visualElement;
|
|
65
|
+
reversedLabels.forEach((key) => {
|
|
66
|
+
const variant = visualElement.getVariant(key);
|
|
67
|
+
variant && setTarget(visualElement, variant);
|
|
68
|
+
if (visualElement.variantChildren) {
|
|
69
|
+
visualElement.variantChildren.forEach((child) => {
|
|
70
|
+
setVariants(mountedStates.get(child.current), variantLabels);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
export {
|
|
76
|
+
animationControls,
|
|
77
|
+
setValues
|
|
78
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ref, onUnmounted } from "vue";
|
|
2
|
-
import { createScopedAnimate } from "
|
|
2
|
+
import { createScopedAnimate } from "../../external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/animation/animate/index.mjs";
|
|
3
3
|
function useAnimate() {
|
|
4
4
|
const dom = ref(null);
|
|
5
5
|
const domProxy = new Proxy(dom, {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { animationControls } from "./animation-controls.mjs";
|
|
2
|
+
import { onMounted, onUnmounted } from "vue";
|
|
3
|
+
function useAnimationControls() {
|
|
4
|
+
const controls = animationControls();
|
|
5
|
+
let unmount;
|
|
6
|
+
onMounted(() => {
|
|
7
|
+
unmount = controls.mount();
|
|
8
|
+
});
|
|
9
|
+
onUnmounted(() => {
|
|
10
|
+
unmount();
|
|
11
|
+
});
|
|
12
|
+
return controls;
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
useAnimationControls
|
|
16
|
+
};
|
|
@@ -2,6 +2,7 @@ import { defineComponent, onMounted, onUnmounted, computed, openBlock, createBlo
|
|
|
2
2
|
import { mountedStates } from "../../state/motion-state.mjs";
|
|
3
3
|
import { provideAnimatePresence, removeDoneCallback, doneCallbacks } from "../presence.mjs";
|
|
4
4
|
import { usePopLayout } from "./use-pop-layout.mjs";
|
|
5
|
+
import { frame } from "../../external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/frameloop/frame.mjs";
|
|
5
6
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
6
7
|
...{
|
|
7
8
|
name: "AnimatePresence",
|
|
@@ -62,9 +63,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
62
63
|
}
|
|
63
64
|
if (!styles.has(state)) {
|
|
64
65
|
state.willUpdate("done");
|
|
66
|
+
} else {
|
|
67
|
+
frame.render(() => {
|
|
68
|
+
removePopStyle(state);
|
|
69
|
+
});
|
|
65
70
|
}
|
|
66
71
|
done();
|
|
67
|
-
removePopStyle(state);
|
|
68
72
|
if (!(el == null ? void 0 : el.isConnected)) {
|
|
69
73
|
state.unmount(true);
|
|
70
74
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { defineComponent, mergeDefaults, useAttrs, getCurrentInstance, onBeforeMount, onMounted, onBeforeUnmount, onUnmounted, onBeforeUpdate, onUpdated, ref, openBlock, createBlock, unref, withCtx, renderSlot } from "vue";
|
|
2
|
-
import { injectMotion, injectLayoutGroup, provideMotion } from "
|
|
3
|
-
import { convertSvgStyleToAttributes, createStyles } from "
|
|
2
|
+
import { injectMotion, injectLayoutGroup, provideMotion } from "../context.mjs";
|
|
3
|
+
import { convertSvgStyleToAttributes, createStyles } from "../../state/style.mjs";
|
|
4
4
|
import { Primitive } from "./Primitive.mjs";
|
|
5
|
-
import { MotionState } from "
|
|
6
|
-
import { injectAnimatePresence } from "
|
|
5
|
+
import { MotionState } from "../../state/motion-state.mjs";
|
|
6
|
+
import { injectAnimatePresence } from "../presence.mjs";
|
|
7
7
|
import { getMotionElement, checkMotionIsHidden } from "./utils.mjs";
|
|
8
|
-
import { useMotionConfig } from "
|
|
9
|
-
import { isMotionValue } from "
|
|
8
|
+
import { useMotionConfig } from "../motion-config/context.mjs";
|
|
9
|
+
import { isMotionValue } from "../../utils/motion-value.mjs";
|
|
10
10
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
11
11
|
...{
|
|
12
12
|
name: "Motion",
|
|
@@ -66,7 +66,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
66
66
|
onPanSessionStart: { type: Function },
|
|
67
67
|
onPanStart: { type: Function },
|
|
68
68
|
onPan: { type: Function },
|
|
69
|
-
onPanEnd: { type: Function }
|
|
69
|
+
onPanEnd: { type: Function },
|
|
70
|
+
focus: {},
|
|
71
|
+
onFocus: { type: Function },
|
|
72
|
+
onBlur: { type: Function }
|
|
70
73
|
}, {
|
|
71
74
|
as: "div",
|
|
72
75
|
asChild: false,
|
|
@@ -79,7 +82,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
79
82
|
layoutScroll: false,
|
|
80
83
|
layoutRoot: false,
|
|
81
84
|
dragListener: true,
|
|
82
|
-
dragElastic: 0.
|
|
85
|
+
dragElastic: 0.5,
|
|
83
86
|
dragMomentum: true,
|
|
84
87
|
whileDrag: void 0,
|
|
85
88
|
crossfade: true
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { defineComponent, h } from "vue";
|
|
2
|
+
import _sfc_main from "./Motion.vue.mjs";
|
|
3
|
+
const componentCache = /* @__PURE__ */ new Map();
|
|
4
|
+
const motion = new Proxy(_sfc_main, {
|
|
5
|
+
get(target, prop) {
|
|
6
|
+
if (typeof prop === "symbol")
|
|
7
|
+
return target[prop];
|
|
8
|
+
let motionComponent = componentCache.get(prop);
|
|
9
|
+
if (prop === "create") {
|
|
10
|
+
return (component) => {
|
|
11
|
+
return defineComponent({
|
|
12
|
+
inheritAttrs: false,
|
|
13
|
+
name: `motion.${component.$name}`,
|
|
14
|
+
setup(_, { attrs, slots }) {
|
|
15
|
+
return () => {
|
|
16
|
+
return h(_sfc_main, {
|
|
17
|
+
...attrs,
|
|
18
|
+
as: component,
|
|
19
|
+
asChild: false
|
|
20
|
+
}, slots);
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
if (!motionComponent) {
|
|
27
|
+
motionComponent = defineComponent({
|
|
28
|
+
inheritAttrs: false,
|
|
29
|
+
name: `motion.${prop}`,
|
|
30
|
+
setup(_, { attrs, slots }) {
|
|
31
|
+
return () => {
|
|
32
|
+
return h(_sfc_main, {
|
|
33
|
+
...attrs,
|
|
34
|
+
as: prop,
|
|
35
|
+
asChild: false
|
|
36
|
+
}, slots);
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
componentCache.set(prop, motionComponent);
|
|
41
|
+
}
|
|
42
|
+
return motionComponent;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
export {
|
|
46
|
+
motion
|
|
47
|
+
};
|
|
@@ -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,43 @@
|
|
|
1
|
+
class DragControls {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.componentControls = /* @__PURE__ */ new Set();
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Subscribe a component's internal `VisualElementDragControls` to the user-facing API.
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
subscribe(controls) {
|
|
11
|
+
this.componentControls.add(controls);
|
|
12
|
+
return () => this.componentControls.delete(controls);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Start a drag gesture on every `motion` component that has this set of drag controls
|
|
16
|
+
* passed into it via the `dragControls` prop.
|
|
17
|
+
*
|
|
18
|
+
* ```jsx
|
|
19
|
+
* dragControls.start(e, {
|
|
20
|
+
* snapToCursor: true
|
|
21
|
+
* })
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @param event - PointerEvent
|
|
25
|
+
* @param options - Options
|
|
26
|
+
*
|
|
27
|
+
* @public
|
|
28
|
+
*/
|
|
29
|
+
start(event, options) {
|
|
30
|
+
this.componentControls.forEach((controls) => {
|
|
31
|
+
controls.start(
|
|
32
|
+
event,
|
|
33
|
+
options
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const createDragControls = () => new DragControls();
|
|
39
|
+
const useDragControls = createDragControls;
|
|
40
|
+
export {
|
|
41
|
+
DragControls,
|
|
42
|
+
useDragControls
|
|
43
|
+
};
|
|
@@ -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
|
+
};
|
|
@@ -19,21 +19,41 @@ class InViewGesture extends Feature {
|
|
|
19
19
|
constructor(state) {
|
|
20
20
|
super(state);
|
|
21
21
|
}
|
|
22
|
-
|
|
22
|
+
startObserver() {
|
|
23
23
|
const element = this.state.element;
|
|
24
24
|
if (!element)
|
|
25
25
|
return;
|
|
26
|
+
this.unmount();
|
|
27
|
+
const { once, ...viewOptions } = this.state.getOptions().inViewOptions || {};
|
|
26
28
|
this.unmount = inView(
|
|
27
29
|
element,
|
|
28
30
|
(entry) => {
|
|
29
31
|
handleHoverEvent(this.state, entry, "Enter");
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
if (!once) {
|
|
33
|
+
return (endEvent) => {
|
|
34
|
+
handleHoverEvent(this.state, entry, "Leave");
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
viewOptions
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
mount() {
|
|
42
|
+
this.startObserver();
|
|
43
|
+
}
|
|
44
|
+
update() {
|
|
45
|
+
const { props, prevProps } = this.state.visualElement;
|
|
46
|
+
const hasOptionsChanged = ["amount", "margin", "root"].some(
|
|
47
|
+
hasViewportOptionChanged(props, prevProps)
|
|
34
48
|
);
|
|
49
|
+
if (hasOptionsChanged) {
|
|
50
|
+
this.startObserver();
|
|
51
|
+
}
|
|
35
52
|
}
|
|
36
53
|
}
|
|
54
|
+
function hasViewportOptionChanged({ inViewOptions = {} }, { inViewOptions: prevViewport = {} } = {}) {
|
|
55
|
+
return (name) => inViewOptions[name] !== prevViewport[name];
|
|
56
|
+
}
|
|
37
57
|
export {
|
|
38
58
|
InViewGesture
|
|
39
59
|
};
|
|
@@ -3,7 +3,7 @@ import { HTMLProjectionNode } from "../../external/.pnpm/framer-motion@11.16.6/e
|
|
|
3
3
|
import { getClosestProjectingNode } from "./utils.mjs";
|
|
4
4
|
import { addScaleCorrector } from "../../external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/projection/styles/scale-correction.mjs";
|
|
5
5
|
import { defaultScaleCorrector } from "./config.mjs";
|
|
6
|
-
import {
|
|
6
|
+
import { isHTMLElement } from "../gestures/drag/utils/is.mjs";
|
|
7
7
|
class ProjectionFeature extends Feature {
|
|
8
8
|
constructor(state) {
|
|
9
9
|
super(state);
|
|
@@ -16,43 +16,17 @@ class ProjectionFeature extends Feature {
|
|
|
16
16
|
options["data-framer-portal-id"] ? void 0 : getClosestProjectingNode(this.state.visualElement.parent)
|
|
17
17
|
);
|
|
18
18
|
this.state.visualElement.projection.isPresent = true;
|
|
19
|
-
this.
|
|
20
|
-
layout: options.layout,
|
|
21
|
-
layoutId: options.layoutId,
|
|
22
|
-
// TODO: drag
|
|
23
|
-
alwaysMeasureLayout: false,
|
|
24
|
-
visualElement: this.state.visualElement,
|
|
25
|
-
animationType: typeof options.layout === "string" ? options.layout : "both",
|
|
26
|
-
// initialPromotionConfig
|
|
27
|
-
layoutRoot: options.layoutRoot,
|
|
28
|
-
layoutScroll: options.layoutScroll,
|
|
29
|
-
crossfade: options.crossfade,
|
|
30
|
-
onExitComplete: () => {
|
|
31
|
-
var _a;
|
|
32
|
-
if (!((_a = this.state.visualElement.projection) == null ? void 0 : _a.isPresent)) {
|
|
33
|
-
const done = doneCallbacks.get(this.state.element);
|
|
34
|
-
this.state.isSafeToRemove = true;
|
|
35
|
-
if (done) {
|
|
36
|
-
done({
|
|
37
|
-
detail: {
|
|
38
|
-
isExit: true
|
|
39
|
-
}
|
|
40
|
-
}, true);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
});
|
|
19
|
+
this.setOptions();
|
|
45
20
|
}
|
|
46
21
|
beforeMount() {
|
|
47
22
|
this.initProjection();
|
|
48
23
|
}
|
|
49
|
-
|
|
24
|
+
setOptions() {
|
|
50
25
|
const options = this.state.options;
|
|
51
26
|
this.state.visualElement.projection.setOptions({
|
|
52
27
|
layout: options.layout,
|
|
53
28
|
layoutId: options.layoutId,
|
|
54
|
-
|
|
55
|
-
alwaysMeasureLayout: false,
|
|
29
|
+
alwaysMeasureLayout: Boolean(options.drag) || options.dragConstraints && isHTMLElement(options.dragConstraints),
|
|
56
30
|
visualElement: this.state.visualElement,
|
|
57
31
|
animationType: typeof options.layout === "string" ? options.layout : "both",
|
|
58
32
|
// initialPromotionConfig
|
|
@@ -61,6 +35,9 @@ class ProjectionFeature extends Feature {
|
|
|
61
35
|
crossfade: options.crossfade
|
|
62
36
|
});
|
|
63
37
|
}
|
|
38
|
+
update() {
|
|
39
|
+
this.setOptions();
|
|
40
|
+
}
|
|
64
41
|
mount() {
|
|
65
42
|
var _a;
|
|
66
43
|
(_a = this.state.visualElement.projection) == null ? void 0 : _a.mount(this.state.element);
|
package/dist/es/index.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { default as default2 } from "./components/
|
|
2
|
-
import { default as default3 } from "./components/LayoutGroup.vue.mjs";
|
|
1
|
+
import { default as default2 } from "./components/LayoutGroup.vue.mjs";
|
|
3
2
|
import { useLayoutGroup } from "./components/use-layout-group.mjs";
|
|
4
3
|
import { injectLayoutGroup, injectMotion, provideLayoutGroup, provideMotion } from "./components/context.mjs";
|
|
5
4
|
import { components, utilities } from "./constants/index.mjs";
|
|
5
|
+
import { useDragControls } from "./features/gestures/drag/use-drag-controls.mjs";
|
|
6
|
+
import { default as default3 } from "./components/motion/Motion.vue.mjs";
|
|
6
7
|
import { default as default4 } from "./components/animate-presence/AnimatePresence.vue.mjs";
|
|
7
8
|
import { default as default5 } from "./components/motion-config/MotionConfig.vue.mjs";
|
|
8
9
|
import { MotionValue, motionValue, motionValue as motionValue2 } from "./external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/value/index.mjs";
|
|
@@ -38,6 +39,7 @@ import { transform } from "./external/.pnpm/framer-motion@11.16.6/external/frame
|
|
|
38
39
|
import { wrap } from "./external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/utils/wrap.mjs";
|
|
39
40
|
import { cancelSync, sync } from "./external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/frameloop/index-legacy.mjs";
|
|
40
41
|
import { cancelFrame, frame, frameData, frameSteps } from "./external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/frameloop/frame.mjs";
|
|
42
|
+
import { motion } from "./components/motion/NameSpace.mjs";
|
|
41
43
|
import { provideMotionConfig, useMotionConfig } from "./components/motion-config/context.mjs";
|
|
42
44
|
import { useComputed } from "./value/use-computed.mjs";
|
|
43
45
|
import { useCombineMotionValues } from "./value/use-combine-values.mjs";
|
|
@@ -48,7 +50,8 @@ import { useMotionValueEvent } from "./value/use-motion-value-event.mjs";
|
|
|
48
50
|
import { useSpring } from "./value/use-spring.mjs";
|
|
49
51
|
import { useScroll } from "./value/use-scroll.mjs";
|
|
50
52
|
import { useVelocity } from "./value/use-velocity.mjs";
|
|
51
|
-
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";
|
|
52
55
|
import { createContext } from "./utils/createContext.mjs";
|
|
53
56
|
import { isMotionValue } from "./utils/motion-value.mjs";
|
|
54
57
|
import { useInView } from "./utils/use-in-view.mjs";
|
|
@@ -57,8 +60,8 @@ import { millisecondsToSeconds, secondsToMilliseconds } from "./utils/time-conve
|
|
|
57
60
|
import { getContextWindow } from "./utils/get-context-window.mjs";
|
|
58
61
|
export {
|
|
59
62
|
default4 as AnimatePresence,
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
default2 as LayoutGroup,
|
|
64
|
+
default3 as Motion,
|
|
62
65
|
default5 as MotionConfig,
|
|
63
66
|
MotionValue,
|
|
64
67
|
animate,
|
|
@@ -99,6 +102,7 @@ export {
|
|
|
99
102
|
millisecondsToSeconds,
|
|
100
103
|
mirrorEasing,
|
|
101
104
|
mix,
|
|
105
|
+
motion,
|
|
102
106
|
motionValue,
|
|
103
107
|
noop,
|
|
104
108
|
pipe,
|
|
@@ -117,9 +121,11 @@ export {
|
|
|
117
121
|
time,
|
|
118
122
|
transform,
|
|
119
123
|
useAnimate,
|
|
124
|
+
useAnimationControls,
|
|
120
125
|
useAnimationFrame,
|
|
121
126
|
useCombineMotionValues,
|
|
122
127
|
useComputed,
|
|
128
|
+
useDragControls,
|
|
123
129
|
useInView,
|
|
124
130
|
useLayoutGroup,
|
|
125
131
|
useMotionConfig,
|
|
@@ -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
|
+
};
|