motion-v 0.5.1 → 0.6.0

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 (51) hide show
  1. package/dist/cjs/index.js +322 -201
  2. package/dist/es/components/LayoutGroup.vue.mjs +10 -4
  3. package/dist/es/components/Motion.vue.mjs +40 -30
  4. package/dist/es/components/{AnimatePresence.vue.mjs → animate-presence/AnimatePresence.vue.mjs} +38 -18
  5. package/dist/es/components/{use-pop-layout.mjs → animate-presence/use-pop-layout.mjs} +5 -0
  6. package/dist/es/components/context.mjs +1 -9
  7. package/dist/es/components/group.mjs +5 -2
  8. package/dist/es/components/motion-config/MotionConfig.vue.mjs +30 -0
  9. package/dist/es/components/motion-config/MotionConfig.vue2.mjs +4 -0
  10. package/dist/es/components/motion-config/context.mjs +17 -0
  11. package/dist/es/components/presence.mjs +0 -2
  12. package/dist/es/components/use-layout-group.mjs +8 -6
  13. package/dist/es/components/utils.mjs +7 -0
  14. package/dist/es/constants/index.mjs +4 -2
  15. package/dist/es/features/layout/layout.mjs +19 -12
  16. package/dist/es/features/layout/projection.mjs +33 -1
  17. package/dist/es/index.mjs +12 -7
  18. package/dist/es/state/animate-variants-children.mjs +6 -4
  19. package/dist/es/state/motion-state.mjs +53 -24
  20. package/dist/es/state/schedule.mjs +2 -26
  21. package/dist/es/state/utils.mjs +0 -9
  22. package/dist/src/components/LayoutGroup.d.ts +4 -1
  23. package/dist/src/components/Motion.d.ts +1 -0
  24. package/dist/src/components/{AnimatePresence.d.ts → animate-presence/AnimatePresence.d.ts} +1 -1
  25. package/dist/src/components/animate-presence/index.d.ts +2 -0
  26. package/dist/src/components/{type.d.ts → animate-presence/types.d.ts} +2 -0
  27. package/dist/src/components/{use-pop-layout.d.ts → animate-presence/use-pop-layout.d.ts} +2 -2
  28. package/dist/src/components/animate-presence/use-presence.d.ts +2 -0
  29. package/dist/src/components/context.d.ts +1 -3
  30. package/dist/src/components/group.d.ts +1 -0
  31. package/dist/src/components/hooks/use-motion-elm.d.ts +13 -0
  32. package/dist/src/components/index.d.ts +2 -0
  33. package/dist/src/components/motion-config/MotionConfig.d.ts +39 -0
  34. package/dist/src/components/motion-config/context.d.ts +11 -0
  35. package/dist/src/components/motion-config/index.d.ts +2 -0
  36. package/dist/src/components/motion-config/types.d.ts +14 -0
  37. package/dist/src/components/presence.d.ts +3 -5
  38. package/dist/src/components/use-layout-group.d.ts +4 -1
  39. package/dist/src/components/use-slot-change-index.d.ts +1 -0
  40. package/dist/src/components/utils.d.ts +7 -0
  41. package/dist/src/features/gestures/drag/types.d.ts +5 -3
  42. package/dist/src/features/gestures/types.d.ts +0 -5
  43. package/dist/src/features/layout/projection.d.ts +1 -0
  44. package/dist/src/features/layout/types.d.ts +1 -0
  45. package/dist/src/index.d.ts +2 -2
  46. package/dist/src/state/animate-variants-children.d.ts +1 -1
  47. package/dist/src/state/event.d.ts +1 -1
  48. package/dist/src/state/motion-state.d.ts +10 -7
  49. package/dist/src/types/state.d.ts +8 -2
  50. package/package.json +3 -2
  51. /package/dist/es/components/{AnimatePresence.vue2.mjs → animate-presence/AnimatePresence.vue2.mjs} +0 -0
@@ -1,5 +1,5 @@
1
- import { defineComponent, renderSlot } from "vue";
2
- import { useLayoutGroup } from "./use-layout-group.mjs";
1
+ import { defineComponent, onBeforeUpdate, renderSlot, unref } from "vue";
2
+ import { useLayoutGroupProvider } from "./use-layout-group.mjs";
3
3
  const _sfc_main = /* @__PURE__ */ defineComponent({
4
4
  __name: "LayoutGroup",
5
5
  props: {
@@ -8,9 +8,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8
8
  },
9
9
  setup(__props) {
10
10
  const props = __props;
11
- useLayoutGroup(props);
11
+ const { forceRender, key, group } = useLayoutGroupProvider(props);
12
+ onBeforeUpdate(() => {
13
+ group.dirty();
14
+ });
12
15
  return (_ctx, _cache) => {
13
- return renderSlot(_ctx.$slots, "default");
16
+ return renderSlot(_ctx.$slots, "default", {
17
+ renderKey: unref(key),
18
+ forceRender: unref(forceRender)
19
+ });
14
20
  };
15
21
  }
16
22
  });
@@ -1,10 +1,11 @@
1
- import { defineComponent, mergeDefaults, ref, useAttrs, getCurrentInstance, onBeforeMount, onMounted, onBeforeUnmount, onUnmounted, onBeforeUpdate, onUpdated, openBlock, createBlock, unref, mergeProps, withCtx, renderSlot } from "vue";
1
+ import { defineComponent, mergeDefaults, useAttrs, getCurrentInstance, onBeforeMount, onMounted, onBeforeUnmount, onUnmounted, onBeforeUpdate, onUpdated, openBlock, createBlock, unref, mergeProps, withCtx, renderSlot } from "vue";
2
2
  import { injectMotion, injectLayoutGroup, provideMotion } from "./context.mjs";
3
3
  import { convertSvgStyleToAttributes, createStyles } from "../state/style.mjs";
4
4
  import { Primitive } from "./Primitive.mjs";
5
5
  import { MotionState } from "../state/motion-state.mjs";
6
6
  import { injectAnimatePresence } from "./presence.mjs";
7
- import { getMotionElement } from "./utils.mjs";
7
+ import { getMotionElement, checkMotionIsHidden } from "./utils.mjs";
8
+ import { useMotionConfig } from "./motion-config/context.mjs";
8
9
  import { isMotionValue } from "../utils/motion-value.mjs";
9
10
  const _sfc_main = /* @__PURE__ */ defineComponent({
10
11
  ...{
@@ -15,6 +16,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
15
16
  props: /* @__PURE__ */ mergeDefaults({
16
17
  as: {},
17
18
  asChild: { type: Boolean },
19
+ whileDrag: {},
18
20
  custom: {},
19
21
  initial: { type: [String, Object, Boolean] },
20
22
  animate: {},
@@ -24,11 +26,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
24
26
  transformTemplate: { type: Function },
25
27
  transition: {},
26
28
  layoutGroup: {},
29
+ motionConfig: {},
30
+ onAnimationComplete: { type: Function },
31
+ onUpdate: { type: Function },
27
32
  layout: { type: [Boolean, String] },
28
33
  layoutId: {},
29
34
  layoutScroll: { type: Boolean },
30
35
  layoutRoot: { type: Boolean },
31
36
  "data-framer-portal-id": {},
37
+ crossfade: { type: Boolean },
32
38
  globalPressTarget: { type: Boolean },
33
39
  press: {},
34
40
  onPressStart: { type: Function },
@@ -74,20 +80,35 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
74
80
  layoutRoot: false,
75
81
  dragListener: true,
76
82
  dragElastic: 0.2,
77
- dragMomentum: true
83
+ dragMomentum: true,
84
+ whileDrag: void 0,
85
+ crossfade: true
78
86
  }),
79
87
  setup(__props) {
80
88
  const props = __props;
81
- const { initial: presenceInitial, safeUnmount } = injectAnimatePresence({ initial: ref(void 0), safeUnmount: () => true });
89
+ const animatePresenceContext = injectAnimatePresence({});
82
90
  const parentState = injectMotion(null);
83
91
  const attrs = useAttrs();
84
92
  const layoutGroup = injectLayoutGroup({});
85
- const state = new MotionState(
86
- {
93
+ const config = useMotionConfig();
94
+ function getLayoutId() {
95
+ if (layoutGroup.id && props.layoutId)
96
+ return `${layoutGroup.id}-${props.layoutId}`;
97
+ return props.layoutId || void 0;
98
+ }
99
+ function getMotionProps() {
100
+ return {
87
101
  ...attrs,
88
102
  ...props,
89
- layoutGroup
90
- },
103
+ layoutId: getLayoutId(),
104
+ transition: props.transition ?? config.value.transition,
105
+ layoutGroup,
106
+ motionConfig: config.value,
107
+ initial: animatePresenceContext.initial === false ? animatePresenceContext.initial : props.initial === true ? void 0 : props.initial
108
+ };
109
+ }
110
+ const state = new MotionState(
111
+ getMotionProps(),
91
112
  parentState
92
113
  );
93
114
  provideMotion(state);
@@ -96,29 +117,20 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
96
117
  state.beforeMount();
97
118
  });
98
119
  onMounted(() => {
99
- state.mount(getMotionElement(instance.$el), {
100
- ...attrs,
101
- ...props,
102
- layoutGroup,
103
- initial: presenceInitial.value === false ? presenceInitial.value : props.initial === true ? void 0 : props.initial
104
- });
105
- });
106
- onBeforeUnmount(() => {
107
- state.beforeUnmount();
120
+ state.mount(getMotionElement(instance.$el), getMotionProps(), checkMotionIsHidden(instance));
108
121
  });
122
+ onBeforeUnmount(() => state.beforeUnmount());
109
123
  onUnmounted(() => {
110
- if (safeUnmount(getMotionElement(instance.$el)))
124
+ const el = getMotionElement(instance.$el);
125
+ if (!(el == null ? void 0 : el.isConnected)) {
111
126
  state.unmount();
127
+ }
112
128
  });
113
129
  onBeforeUpdate(() => {
114
130
  state.beforeUpdate();
115
131
  });
116
132
  onUpdated(() => {
117
- state.update({
118
- ...attrs,
119
- ...props,
120
- initial: presenceInitial.value === false ? presenceInitial.value : props.initial === true ? void 0 : props.initial
121
- });
133
+ state.update(getMotionProps());
122
134
  });
123
135
  function getProps() {
124
136
  const isSVG = state.visualElement.type === "svg";
@@ -137,7 +149,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
137
149
  Object.assign(styleProps, style);
138
150
  }
139
151
  if (!state.isMounted()) {
140
- Object.assign(styleProps, state.target);
152
+ Object.assign(styleProps, state.baseTarget);
141
153
  }
142
154
  if (props.drag && props.dragListener !== false) {
143
155
  Object.assign(styleProps, {
@@ -155,18 +167,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
155
167
  return attrsProps;
156
168
  }
157
169
  return (_ctx, _cache) => {
158
- var _a, _b;
159
- return openBlock(), createBlock(unref(Primitive), mergeProps({
170
+ return openBlock(), createBlock(unref(Primitive), mergeProps(getProps(), {
160
171
  as: _ctx.as,
161
- "as-child": _ctx.asChild
162
- }, getProps(), {
163
- "data-layout-group-key": (_b = (_a = unref(layoutGroup)) == null ? void 0 : _a.key) == null ? void 0 : _b.value
172
+ "as-child": _ctx.asChild,
173
+ "data-motion-id": unref(state).id
164
174
  }), {
165
175
  default: withCtx(() => [
166
176
  renderSlot(_ctx.$slots, "default")
167
177
  ]),
168
178
  _: 3
169
- }, 16, ["as", "as-child", "data-layout-group-key"]);
179
+ }, 16, ["as", "as-child", "data-motion-id"]);
170
180
  };
171
181
  }
172
182
  });
@@ -1,8 +1,8 @@
1
- import { defineComponent, toRefs, openBlock, createBlock, resolveDynamicComponent, TransitionGroup, Transition, withCtx, renderSlot } from "vue";
2
- import { mountedStates } from "../state/motion-state.mjs";
3
- import { provideAnimatePresence, doneCallbacks, removeDoneCallback } from "./presence.mjs";
4
- import { useLayoutGroup } from "./use-layout-group.mjs";
1
+ import { defineComponent, onMounted, onUnmounted, openBlock, createBlock, resolveDynamicComponent, TransitionGroup, Transition, withCtx, renderSlot } from "vue";
2
+ import { mountedStates } from "../../state/motion-state.mjs";
3
+ import { provideAnimatePresence, removeDoneCallback, doneCallbacks } from "../presence.mjs";
5
4
  import { usePopLayout } from "./use-pop-layout.mjs";
5
+ import { createStyles } from "../../state/style.mjs";
6
6
  const _sfc_main = /* @__PURE__ */ defineComponent({
7
7
  ...{
8
8
  name: "AnimatePresence",
@@ -13,44 +13,64 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
13
13
  mode: { default: "sync" },
14
14
  initial: { type: Boolean, default: true },
15
15
  multiple: { type: Boolean, default: false },
16
- as: {}
16
+ as: {},
17
+ custom: {},
18
+ onExitComplete: {}
17
19
  },
18
20
  setup(__props) {
19
21
  const props = __props;
20
- const { initial } = toRefs(props);
21
- provideAnimatePresence({
22
- initial,
23
- safeUnmount(el) {
24
- return !doneCallbacks.has(el);
25
- }
22
+ const presenceContext = {
23
+ initial: props.initial,
24
+ custom: props.custom
25
+ };
26
+ provideAnimatePresence(presenceContext);
27
+ onMounted(() => {
28
+ presenceContext.initial = void 0;
26
29
  });
27
30
  function enter(el) {
28
31
  const state = mountedStates.get(el);
32
+ const motionStateId = el.dataset.motionId;
33
+ const motionState = mountedStates.get(motionStateId);
34
+ if (motionState) {
35
+ const baseStyle = createStyles(motionState.baseTarget);
36
+ Object.assign(el.style, baseStyle);
37
+ }
29
38
  if (!state) {
30
39
  return;
31
40
  }
32
41
  removeDoneCallback(el);
33
42
  state.setActive("exit", false);
34
43
  }
35
- const layoutGroup = useLayoutGroup(props);
36
44
  const { addPopStyle, removePopStyle } = usePopLayout(props);
45
+ const exitDom = /* @__PURE__ */ new Map();
46
+ onUnmounted(() => {
47
+ exitDom.clear();
48
+ });
37
49
  function exit(el, done) {
38
50
  const state = mountedStates.get(el);
39
51
  if (!state) {
40
52
  return done();
41
53
  }
54
+ exitDom.set(el, true);
42
55
  removeDoneCallback(el);
43
56
  addPopStyle(state);
44
57
  function doneCallback(e) {
45
- var _a, _b, _c;
46
- removePopStyle(state);
58
+ var _a, _b;
47
59
  if ((_a = e == null ? void 0 : e.detail) == null ? void 0 : _a.isExit) {
60
+ const projection = state.visualElement.projection;
61
+ if ((projection == null ? void 0 : projection.animationProgress) > 0 && !state.isSafeToRemove) {
62
+ return;
63
+ }
64
+ state.willUpdate("done");
65
+ removePopStyle(state);
48
66
  removeDoneCallback(el);
49
- (_b = state.visualElement.projection) == null ? void 0 : _b.willUpdate();
50
- (_c = layoutGroup.forceRender) == null ? void 0 : _c.call(layoutGroup);
67
+ exitDom.delete(el);
68
+ if (exitDom.size === 0) {
69
+ (_b = props.onExitComplete) == null ? void 0 : _b.call(props);
70
+ }
51
71
  done();
52
- if (!el.isConnected) {
53
- state.unmount();
72
+ if (!(el == null ? void 0 : el.isConnected)) {
73
+ state.unmount(true);
54
74
  }
55
75
  }
56
76
  }
@@ -1,5 +1,7 @@
1
+ import { useMotionConfig } from "../motion-config/context.mjs";
1
2
  function usePopLayout(props) {
2
3
  const styles = /* @__PURE__ */ new WeakMap();
4
+ const config = useMotionConfig();
3
5
  function addPopStyle(state) {
4
6
  if (props.mode !== "popLayout")
5
7
  return;
@@ -11,6 +13,9 @@ function usePopLayout(props) {
11
13
  };
12
14
  state.element.dataset.motionPopId = state.id;
13
15
  const style = document.createElement("style");
16
+ if (config.value.nonce) {
17
+ style.nonce = config.value.nonce;
18
+ }
14
19
  styles.set(state, style);
15
20
  document.head.appendChild(style);
16
21
  style.textContent = `
@@ -1,17 +1,9 @@
1
1
  import { createContext } from "../utils/createContext.mjs";
2
2
  const [injectMotion, provideMotion] = createContext("Motion");
3
3
  const [injectLayoutGroup, provideLayoutGroup] = createContext("LayoutGroup");
4
- function shouldInheritGroup(inherit) {
5
- return inherit === true;
6
- }
7
- function shouldInheritId(inherit) {
8
- return shouldInheritGroup(inherit === true) || inherit === "id";
9
- }
10
4
  export {
11
5
  injectLayoutGroup,
12
6
  injectMotion,
13
7
  provideLayoutGroup,
14
- provideMotion,
15
- shouldInheritGroup,
16
- shouldInheritId
8
+ provideMotion
17
9
  };
@@ -20,9 +20,12 @@ function nodeGroup() {
20
20
  unsubscribe();
21
21
  subscriptions.delete(node);
22
22
  }
23
- dirtyAll();
24
23
  },
25
- dirty: dirtyAll
24
+ dirty: dirtyAll,
25
+ didUpdate: () => {
26
+ var _a;
27
+ (_a = nodes[0]) == null ? void 0 : _a.didUpdate();
28
+ }
26
29
  };
27
30
  }
28
31
  export {
@@ -0,0 +1,30 @@
1
+ import { defineComponent, computed, renderSlot } from "vue";
2
+ import { defaultConfig, useMotionConfig, provideMotionConfig } from "./context.mjs";
3
+ const _sfc_main = /* @__PURE__ */ defineComponent({
4
+ ...{
5
+ name: "MotionConfig",
6
+ inheritAttrs: false
7
+ },
8
+ __name: "MotionConfig",
9
+ props: {
10
+ transition: {},
11
+ reduceMotion: { default: defaultConfig.reduceMotion },
12
+ nonce: {}
13
+ },
14
+ setup(__props) {
15
+ const props = __props;
16
+ const parentConfig = useMotionConfig();
17
+ const config = computed(() => ({
18
+ transition: props.transition ?? parentConfig.value.transition,
19
+ reduceMotion: props.reduceMotion ?? parentConfig.value.reduceMotion,
20
+ nonce: props.nonce ?? parentConfig.value.nonce
21
+ }));
22
+ provideMotionConfig(config);
23
+ return (_ctx, _cache) => {
24
+ return renderSlot(_ctx.$slots, "default");
25
+ };
26
+ }
27
+ });
28
+ export {
29
+ _sfc_main as default
30
+ };
@@ -0,0 +1,4 @@
1
+ import _sfc_main from "./MotionConfig.vue.mjs";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,17 @@
1
+ import { computed } from "vue";
2
+ import { createContext } from "../../utils/createContext.mjs";
3
+ const defaultConfig = {
4
+ reduceMotion: "never",
5
+ transition: void 0,
6
+ nonce: void 0
7
+ };
8
+ const [injectMotionConfig, provideMotionConfig] = createContext("MotionConfig");
9
+ function useMotionConfig() {
10
+ return injectMotionConfig(computed(() => defaultConfig));
11
+ }
12
+ export {
13
+ defaultConfig,
14
+ injectMotionConfig,
15
+ provideMotionConfig,
16
+ useMotionConfig
17
+ };
@@ -1,7 +1,5 @@
1
- import { ref } from "vue";
2
1
  import { createContext } from "../utils/createContext.mjs";
3
2
  const doneCallbacks = /* @__PURE__ */ new WeakMap();
4
- ref(/* @__PURE__ */ new WeakMap());
5
3
  function removeDoneCallback(element) {
6
4
  const prevDoneCallback = doneCallbacks.get(element);
7
5
  if (prevDoneCallback) {
@@ -1,8 +1,7 @@
1
- import { watch } from "vue";
2
1
  import { injectLayoutGroup, provideLayoutGroup } from "./context.mjs";
3
2
  import { useForceUpdate } from "./use-force-update.mjs";
4
3
  import { nodeGroup } from "./group.mjs";
5
- function useLayoutGroup(props) {
4
+ function useLayoutGroupProvider(props) {
6
5
  const parentGroup = injectLayoutGroup(null);
7
6
  const [forceRender, key] = useForceUpdate();
8
7
  const context = {
@@ -11,12 +10,14 @@ function useLayoutGroup(props) {
11
10
  forceRender,
12
11
  key
13
12
  };
14
- watch(key, () => {
15
- context.id = getGroupId(props, parentGroup);
16
- });
17
13
  provideLayoutGroup(context);
18
14
  return context;
19
15
  }
16
+ function useLayoutGroup() {
17
+ const { forceRender } = injectLayoutGroup({ forceRender: () => {
18
+ } });
19
+ return { forceRender };
20
+ }
20
21
  function getGroupId(props, parentGroup) {
21
22
  const shouldInherit = props.inherit === true || props.inherit === "id";
22
23
  const parentId = parentGroup == null ? void 0 : parentGroup.id;
@@ -30,5 +31,6 @@ function getGroup(props, parentGroup) {
30
31
  return shouldInherit ? (parentGroup == null ? void 0 : parentGroup.group) || nodeGroup() : nodeGroup();
31
32
  }
32
33
  export {
33
- useLayoutGroup
34
+ useLayoutGroup,
35
+ useLayoutGroupProvider
34
36
  };
@@ -3,6 +3,13 @@ function getMotionElement(el) {
3
3
  return getMotionElement(el.nextSibling);
4
4
  return el;
5
5
  }
6
+ function checkMotionIsHidden(instance) {
7
+ var _a;
8
+ const isHidden = ((_a = getMotionElement(instance.$el)) == null ? void 0 : _a.style.display) === "none";
9
+ const hasTransition = instance.$.vnode.transition;
10
+ return hasTransition && isHidden;
11
+ }
6
12
  export {
13
+ checkMotionIsHidden,
7
14
  getMotionElement
8
15
  };
@@ -2,7 +2,8 @@ const components = {
2
2
  motion: [
3
3
  "Motion",
4
4
  "AnimatePresence",
5
- "LayoutGroup"
5
+ "LayoutGroup",
6
+ "MotionConfig"
6
7
  ]
7
8
  };
8
9
  const utilities = {
@@ -17,7 +18,8 @@ const utilities = {
17
18
  "useAnimate",
18
19
  "useInView",
19
20
  "useAnimationFrame",
20
- "useMotionValueEvent"
21
+ "useMotionValueEvent",
22
+ "useLayoutGroup"
21
23
  ]
22
24
  };
23
25
  export {
@@ -8,13 +8,11 @@ class LayoutFeature extends Feature {
8
8
  addScaleCorrector(defaultScaleCorrector);
9
9
  }
10
10
  beforeUpdate() {
11
- var _a;
12
- (_a = this.state.visualElement.projection) == null ? void 0 : _a.willUpdate();
11
+ this.state.willUpdate("beforeUpdate");
13
12
  }
14
13
  update() {
15
- var _a, _b;
16
- (_a = this.state.visualElement.projection) == null ? void 0 : _a.setOptions(this.state.options);
17
- (_b = this.state.visualElement.projection) == null ? void 0 : _b.root.didUpdate();
14
+ var _a;
15
+ (_a = this.state.visualElement.projection) == null ? void 0 : _a.root.didUpdate();
18
16
  }
19
17
  beforeMount() {
20
18
  }
@@ -32,16 +30,25 @@ class LayoutFeature extends Feature {
32
30
  }
33
31
  }
34
32
  beforeUnmount() {
35
- if (this.state.visualElement.projection) {
36
- this.state.visualElement.projection.willUpdate();
33
+ const projection = this.state.visualElement.projection;
34
+ if (projection) {
35
+ this.state.willUpdate("beforeUnmount");
36
+ if (this.state.options.layoutId) {
37
+ projection.isPresent = false;
38
+ projection.relegate();
39
+ } else if (this.state.options.layout) {
40
+ this.state.isSafeToRemove = true;
41
+ }
37
42
  }
38
43
  }
39
44
  unmount() {
40
- if (this.state.visualElement.projection) {
41
- this.state.visualElement.projection.unmount();
42
- const layoutGroup = this.state.options.layoutGroup;
43
- if (layoutGroup == null ? void 0 : layoutGroup.group)
44
- layoutGroup.group.remove(this.state.visualElement.projection);
45
+ var _a, _b;
46
+ const layoutGroup = this.state.options.layoutGroup;
47
+ const projection = this.state.visualElement.projection;
48
+ if ((layoutGroup == null ? void 0 : layoutGroup.group) && projection)
49
+ layoutGroup.group.remove(projection);
50
+ if (this.state.options.layoutId || this.state.options.layout) {
51
+ (_b = (_a = this.state.visualElement.projection) == null ? void 0 : _a.root) == null ? void 0 : _b.didUpdate();
45
52
  }
46
53
  }
47
54
  }
@@ -3,6 +3,7 @@ import { HTMLProjectionNode } from "../../external/.pnpm/framer-motion@11.15.0/e
3
3
  import { getClosestProjectingNode } from "./utils.mjs";
4
4
  import { addScaleCorrector } from "../../external/.pnpm/framer-motion@11.15.0/external/framer-motion/dist/es/projection/styles/scale-correction.mjs";
5
5
  import { defaultScaleCorrector } from "./config.mjs";
6
+ import { doneCallbacks } from "../../components/presence.mjs";
6
7
  class ProjectionFeature extends Feature {
7
8
  constructor(state) {
8
9
  super(state);
@@ -14,6 +15,7 @@ class ProjectionFeature extends Feature {
14
15
  this.state.visualElement.latestValues,
15
16
  options["data-framer-portal-id"] ? void 0 : getClosestProjectingNode(this.state.visualElement.parent)
16
17
  );
18
+ this.state.visualElement.projection.isPresent = true;
17
19
  this.state.visualElement.projection.setOptions({
18
20
  layout: options.layout,
19
21
  layoutId: options.layoutId,
@@ -23,12 +25,42 @@ class ProjectionFeature extends Feature {
23
25
  animationType: typeof options.layout === "string" ? options.layout : "both",
24
26
  // initialPromotionConfig
25
27
  layoutRoot: options.layoutRoot,
26
- layoutScroll: options.layoutScroll
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
+ }
27
44
  });
28
45
  }
29
46
  beforeMount() {
30
47
  this.initProjection();
31
48
  }
49
+ update() {
50
+ const options = this.state.options;
51
+ this.state.visualElement.projection.setOptions({
52
+ layout: options.layout,
53
+ layoutId: options.layoutId,
54
+ // TODO: drag
55
+ alwaysMeasureLayout: false,
56
+ visualElement: this.state.visualElement,
57
+ animationType: typeof options.layout === "string" ? options.layout : "both",
58
+ // initialPromotionConfig
59
+ layoutRoot: options.layoutRoot,
60
+ layoutScroll: options.layoutScroll,
61
+ crossfade: options.crossfade
62
+ });
63
+ }
32
64
  mount() {
33
65
  var _a;
34
66
  (_a = this.state.visualElement.projection) == null ? void 0 : _a.mount(this.state.element);
package/dist/es/index.mjs CHANGED
@@ -1,8 +1,10 @@
1
1
  import { default as default2 } from "./components/Motion.vue.mjs";
2
- import { default as default3 } from "./components/AnimatePresence.vue.mjs";
3
- import { default as default4 } from "./components/LayoutGroup.vue.mjs";
4
- import { injectLayoutGroup, injectMotion, provideLayoutGroup, provideMotion, shouldInheritGroup, shouldInheritId } from "./components/context.mjs";
2
+ import { default as default3 } from "./components/LayoutGroup.vue.mjs";
3
+ import { useLayoutGroup } from "./components/use-layout-group.mjs";
4
+ import { injectLayoutGroup, injectMotion, provideLayoutGroup, provideMotion } from "./components/context.mjs";
5
5
  import { components, utilities } from "./constants/index.mjs";
6
+ import { default as default4 } from "./components/animate-presence/AnimatePresence.vue.mjs";
7
+ import { default as default5 } from "./components/motion-config/MotionConfig.vue.mjs";
6
8
  import { MotionValue, motionValue, motionValue as motionValue2 } from "./external/.pnpm/framer-motion@11.15.0/external/framer-motion/dist/es/value/index.mjs";
7
9
  import { invariant } from "./external/.pnpm/motion-utils@11.14.3/external/motion-utils/dist/es/errors.mjs";
8
10
  import { noop } from "./external/.pnpm/motion-utils@11.14.3/external/motion-utils/dist/es/noop.mjs";
@@ -36,6 +38,7 @@ import { wrap } from "./external/.pnpm/framer-motion@11.15.0/external/framer-mot
36
38
  import { time } from "./external/.pnpm/framer-motion@11.15.0/external/framer-motion/dist/es/frameloop/sync-time.mjs";
37
39
  import { cancelSync, sync } from "./external/.pnpm/framer-motion@11.15.0/external/framer-motion/dist/es/frameloop/index-legacy.mjs";
38
40
  import { cancelFrame, frame, frameData, frameSteps } from "./external/.pnpm/framer-motion@11.15.0/external/framer-motion/dist/es/frameloop/frame.mjs";
41
+ import { provideMotionConfig, useMotionConfig } from "./components/motion-config/context.mjs";
39
42
  import { useComputed } from "./value/use-computed.mjs";
40
43
  import { useCombineMotionValues } from "./value/use-combine-values.mjs";
41
44
  import { useTransform } from "./value/use-transform.mjs";
@@ -53,9 +56,10 @@ import { useAnimationFrame } from "./utils/use-animation-frame.mjs";
53
56
  import { millisecondsToSeconds, secondsToMilliseconds } from "./utils/time-conversion.mjs";
54
57
  import { getContextWindow } from "./utils/get-context-window.mjs";
55
58
  export {
56
- default3 as AnimatePresence,
57
- default4 as LayoutGroup,
59
+ default4 as AnimatePresence,
60
+ default3 as LayoutGroup,
58
61
  default2 as Motion,
62
+ default5 as MotionConfig,
59
63
  MotionValue,
60
64
  animate,
61
65
  animateMini,
@@ -101,12 +105,11 @@ export {
101
105
  progress,
102
106
  provideLayoutGroup,
103
107
  provideMotion,
108
+ provideMotionConfig,
104
109
  reverseEasing,
105
110
  scroll,
106
111
  scrollInfo,
107
112
  secondsToMilliseconds,
108
- shouldInheritGroup,
109
- shouldInheritId,
110
113
  spring,
111
114
  stagger,
112
115
  steps,
@@ -118,6 +121,8 @@ export {
118
121
  useCombineMotionValues,
119
122
  useComputed,
120
123
  useInView,
124
+ useLayoutGroup,
125
+ useMotionConfig,
121
126
  useMotionTemplate,
122
127
  motionValue2 as useMotionValue,
123
128
  useMotionValueEvent,
@@ -2,7 +2,7 @@ import { style } from "./style.mjs";
2
2
  import { transformResetValue } from "./transform.mjs";
3
3
  import { resolveVariant, hasChanged, getOptions } from "./utils.mjs";
4
4
  import { animate } from "../external/.pnpm/framer-motion@11.15.0/external/framer-motion/dist/es/animation/animate/index.mjs";
5
- function animateVariantsChildren(state, activeState) {
5
+ function animateVariantsChildren(state, activeState, isFirstAnimate = false) {
6
6
  const variantChildren = state.visualElement.variantChildren;
7
7
  if (!(variantChildren == null ? void 0 : variantChildren.size)) {
8
8
  return {
@@ -13,13 +13,15 @@ function animateVariantsChildren(state, activeState) {
13
13
  const animationFactories = [];
14
14
  Array.from(variantChildren).forEach((child, index) => {
15
15
  var _a;
16
- const prevTarget = child.state.target;
16
+ const prevTarget = isFirstAnimate ? child.state.baseTarget : child.state.target;
17
17
  const childState = child.state;
18
18
  childState.target = {};
19
19
  for (const name in activeState) {
20
- childState.activeStates[name] = true;
20
+ if (name === "initial" && !isFirstAnimate) {
21
+ continue;
22
+ }
21
23
  const { definition, transition } = activeState[name];
22
- const { staggerChildren = 0, staggerDirection = 1, delayChildren = 0 } = transition;
24
+ const { staggerChildren = 0, staggerDirection = 1, delayChildren = 0 } = transition || {};
23
25
  const maxStaggerDuration = (variantChildren.size - 1) * staggerChildren;
24
26
  const generateStaggerDuration = staggerDirection === 1 ? (i = 0) => i * staggerChildren : (i = 0) => maxStaggerDuration - i * staggerChildren;
25
27
  const variant = resolveVariant(