motion-v 0.9.0 → 0.10.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.
package/dist/cjs/index.js CHANGED
@@ -5082,6 +5082,26 @@ const svgElementSet = new Set(svgElements);
5082
5082
  function isSVGElement$1(as) {
5083
5083
  return svgElementSet.has(as);
5084
5084
  }
5085
+ function isAnimateChanged(oldOptions, newOptions) {
5086
+ const oldAnimate = oldOptions.animate;
5087
+ const newAnimate = newOptions.animate;
5088
+ if (oldAnimate === newAnimate)
5089
+ return false;
5090
+ if (!oldAnimate || !newAnimate)
5091
+ return true;
5092
+ if (typeof oldAnimate === "object" || typeof newAnimate === "object") {
5093
+ const oldKeys = Object.keys(oldAnimate);
5094
+ const newKeys = Object.keys(newAnimate);
5095
+ if (oldKeys.length !== newKeys.length)
5096
+ return true;
5097
+ return oldKeys.some((key) => {
5098
+ const oldVal = oldAnimate[key];
5099
+ const newVal = newAnimate[key];
5100
+ return oldVal !== newVal;
5101
+ });
5102
+ }
5103
+ return oldAnimate !== newAnimate;
5104
+ }
5085
5105
  const rotation = {
5086
5106
  syntax: "<angle>",
5087
5107
  initialValue: "0deg",
@@ -6405,19 +6425,18 @@ class LayoutFeature extends Feature {
6405
6425
  if (this.state.options.layout || this.state.options.layoutId)
6406
6426
  (_b = (_a = this.state.visualElement.projection) == null ? void 0 : _a.root) == null ? void 0 : _b.didUpdate();
6407
6427
  }
6408
- beforeMount() {
6409
- }
6410
6428
  mount() {
6411
6429
  var _a;
6412
6430
  const options = this.state.options;
6413
6431
  const layoutGroup = this.state.options.layoutGroup;
6414
- if (options.layout || options.layoutId) {
6432
+ if (options.layout || options.layoutId || options.drag) {
6415
6433
  const projection = this.state.visualElement.projection;
6416
6434
  if (projection) {
6435
+ projection.promote();
6417
6436
  (_a = layoutGroup == null ? void 0 : layoutGroup.group) == null ? void 0 : _a.add(projection);
6418
6437
  }
6419
- globalProjectionState.hasEverUpdated = true;
6420
6438
  this.didUpdate();
6439
+ globalProjectionState.hasEverUpdated = true;
6421
6440
  }
6422
6441
  }
6423
6442
  beforeUnmount() {
@@ -6435,9 +6454,11 @@ class LayoutFeature extends Feature {
6435
6454
  unmount() {
6436
6455
  const layoutGroup = this.state.options.layoutGroup;
6437
6456
  const projection = this.state.visualElement.projection;
6438
- if ((layoutGroup == null ? void 0 : layoutGroup.group) && projection)
6457
+ if ((layoutGroup == null ? void 0 : layoutGroup.group) && projection) {
6439
6458
  layoutGroup.group.remove(projection);
6440
- this.didUpdate();
6459
+ } else {
6460
+ this.didUpdate();
6461
+ }
6441
6462
  }
6442
6463
  }
6443
6464
  function asyncHandler(handler) {
@@ -8185,6 +8206,7 @@ function executeAnimations(factories, getChildAnimations, childAnimations, trans
8185
8206
  }
8186
8207
  const mountedStates = /* @__PURE__ */ new WeakMap();
8187
8208
  let id = 0;
8209
+ const mountedLayoutIds = /* @__PURE__ */ new Set();
8188
8210
  class MotionState {
8189
8211
  constructor(options, parent) {
8190
8212
  var _a;
@@ -8228,7 +8250,7 @@ class MotionState {
8228
8250
  this.initTarget(initialVariantSource);
8229
8251
  this.featureManager = new FeatureManager(this);
8230
8252
  }
8231
- // Get animation context, falling back to parent context
8253
+ // Get animation context, falling back to parent context for inheritance
8232
8254
  get context() {
8233
8255
  if (!this._context) {
8234
8256
  const handler = {
@@ -8249,10 +8271,6 @@ class MotionState {
8249
8271
  }
8250
8272
  this.target = {};
8251
8273
  }
8252
- // Get initial animation state
8253
- get initial() {
8254
- return core.isDef(this.options.initial) ? this.options.initial : this.context.initial;
8255
- }
8256
8274
  // Update visual element with new options
8257
8275
  updateOptions() {
8258
8276
  this.visualElement.update({
@@ -8265,10 +8283,11 @@ class MotionState {
8265
8283
  isPresent: !doneCallbacks.has(this.element)
8266
8284
  });
8267
8285
  }
8286
+ // Called before mounting, executes in parent-to-child order
8268
8287
  beforeMount() {
8269
8288
  this.featureManager.beforeMount();
8270
8289
  }
8271
- // Mount motion state to DOM element
8290
+ // Mount motion state to DOM element, handles parent-child relationships
8272
8291
  mount(element, options, notAnimate = false) {
8273
8292
  heyListen.invariant(
8274
8293
  Boolean(element),
@@ -8287,51 +8306,66 @@ class MotionState {
8287
8306
  if (!notAnimate && this.options.animate) {
8288
8307
  this.animateUpdates();
8289
8308
  }
8309
+ if (this.options.layoutId) {
8310
+ mountedLayoutIds.add(this.options.layoutId);
8311
+ frame.render(() => {
8312
+ mountedLayoutIds.clear();
8313
+ });
8314
+ }
8290
8315
  }
8316
+ // Called before unmounting, executes in child-to-parent order
8291
8317
  beforeUnmount() {
8292
8318
  this.featureManager.beforeUnmount();
8293
8319
  }
8294
8320
  // Unmount motion state and optionally unmount children
8321
+ // Handles unmounting in the correct order based on component tree
8295
8322
  unmount(unMountChildren = false) {
8296
- var _a, _b, _c;
8297
- mountedStates.delete(this.element);
8298
- this.featureManager.unmount();
8299
- if (unMountChildren) {
8300
- frame.render(() => {
8301
- var _a2;
8302
- (_a2 = this.visualElement) == null ? void 0 : _a2.unmount();
8323
+ const shouldDelay = this.options.layoutId && !mountedLayoutIds.has(this.options.layoutId);
8324
+ const unmount = () => {
8325
+ var _a, _b, _c;
8326
+ mountedStates.delete(this.element);
8327
+ this.featureManager.unmount();
8328
+ if (unMountChildren && !shouldDelay) {
8329
+ frame.render(() => {
8330
+ var _a2;
8331
+ (_a2 = this.visualElement) == null ? void 0 : _a2.unmount();
8332
+ });
8333
+ } else {
8334
+ (_a = this.visualElement) == null ? void 0 : _a.unmount();
8335
+ }
8336
+ if (unMountChildren) {
8337
+ const unmountChild = (child) => {
8338
+ var _a2;
8339
+ child.unmount(true);
8340
+ (_a2 = child.children) == null ? void 0 : _a2.forEach(unmountChild);
8341
+ };
8342
+ Array.from(this.children).forEach(unmountChild);
8343
+ }
8344
+ (_c = (_b = this.parent) == null ? void 0 : _b.children) == null ? void 0 : _c.delete(this);
8345
+ };
8346
+ if (shouldDelay) {
8347
+ Promise.resolve().then(() => {
8348
+ unmount();
8303
8349
  });
8304
8350
  } else {
8305
- (_a = this.visualElement) == null ? void 0 : _a.unmount();
8306
- }
8307
- if (unMountChildren) {
8308
- const unmountChild = (child) => {
8309
- var _a2;
8310
- child.unmount(true);
8311
- (_a2 = child.children) == null ? void 0 : _a2.forEach(unmountChild);
8312
- };
8313
- Array.from(this.children).forEach(unmountChild);
8351
+ unmount();
8314
8352
  }
8315
- (_c = (_b = this.parent) == null ? void 0 : _b.children) == null ? void 0 : _c.delete(this);
8316
8353
  }
8354
+ // Called before updating, executes in parent-to-child order
8317
8355
  beforeUpdate() {
8318
8356
  this.featureManager.beforeUpdate();
8319
8357
  }
8320
8358
  // Update motion state with new options
8321
- update(options, notAnimate = false) {
8322
- const prevAnimate = JSON.stringify(this.options.animate);
8359
+ update(options) {
8360
+ const hasAnimateChange = isAnimateChanged(this.options, options);
8323
8361
  this.options = options;
8324
- let hasAnimateChange = false;
8325
- if (prevAnimate !== JSON.stringify(options.animate)) {
8326
- hasAnimateChange = true;
8327
- }
8328
8362
  this.updateOptions();
8329
8363
  this.featureManager.update();
8330
- if (hasAnimateChange && !notAnimate) {
8364
+ if (hasAnimateChange) {
8331
8365
  this.animateUpdates();
8332
8366
  }
8333
8367
  }
8334
- // Set animation state active status
8368
+ // Set animation state active status and propagate to children
8335
8369
  setActive(name, isActive, isAnimate = true) {
8336
8370
  var _a;
8337
8371
  if (!this.element || this.activeStates[name] === isActive)
@@ -8352,10 +8386,12 @@ class MotionState {
8352
8386
  getOptions() {
8353
8387
  return this.options;
8354
8388
  }
8389
+ // Called before layout updates to prepare for changes
8355
8390
  willUpdate(label) {
8356
8391
  var _a;
8357
- if (this.options.layout || this.options.layoutId)
8392
+ if (this.options.layout || this.options.layoutId) {
8358
8393
  (_a = this.visualElement.projection) == null ? void 0 : _a.willUpdate();
8394
+ }
8359
8395
  }
8360
8396
  }
8361
8397
  function getMotionElement(el) {
@@ -8378,7 +8414,7 @@ const [injectMotionConfig, provideMotionConfig] = createContext("MotionConfig");
8378
8414
  function useMotionConfig() {
8379
8415
  return injectMotionConfig(vue.computed(() => defaultConfig));
8380
8416
  }
8381
- const _sfc_main$5 = /* @__PURE__ */ vue.defineComponent({
8417
+ const _sfc_main$6 = /* @__PURE__ */ vue.defineComponent({
8382
8418
  ...{
8383
8419
  name: "Motion",
8384
8420
  inheritAttrs: false
@@ -8571,7 +8607,7 @@ const _sfc_main$5 = /* @__PURE__ */ vue.defineComponent({
8571
8607
  }
8572
8608
  });
8573
8609
  const componentCache = /* @__PURE__ */ new Map();
8574
- const motion = new Proxy(_sfc_main$5, {
8610
+ const motion = new Proxy(_sfc_main$6, {
8575
8611
  get(target, prop) {
8576
8612
  if (typeof prop === "symbol")
8577
8613
  return target[prop];
@@ -8583,7 +8619,7 @@ const motion = new Proxy(_sfc_main$5, {
8583
8619
  name: `motion.${component.$name}`,
8584
8620
  setup(_, { attrs, slots }) {
8585
8621
  return () => {
8586
- return vue.h(_sfc_main$5, {
8622
+ return vue.h(_sfc_main$6, {
8587
8623
  ...attrs,
8588
8624
  as: component,
8589
8625
  asChild: false
@@ -8599,7 +8635,7 @@ const motion = new Proxy(_sfc_main$5, {
8599
8635
  name: `motion.${prop}`,
8600
8636
  setup(_, { attrs, slots }) {
8601
8637
  return () => {
8602
- return vue.h(_sfc_main$5, {
8638
+ return vue.h(_sfc_main$6, {
8603
8639
  ...attrs,
8604
8640
  as: prop,
8605
8641
  asChild: false
@@ -8663,7 +8699,7 @@ function usePopLayout(props) {
8663
8699
  styles
8664
8700
  };
8665
8701
  }
8666
- const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
8702
+ const _sfc_main$5 = /* @__PURE__ */ vue.defineComponent({
8667
8703
  ...{
8668
8704
  name: "AnimatePresence",
8669
8705
  inheritAttrs: true
@@ -8675,7 +8711,8 @@ const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
8675
8711
  multiple: { type: Boolean, default: false },
8676
8712
  as: {},
8677
8713
  custom: {},
8678
- onExitComplete: {}
8714
+ onExitComplete: {},
8715
+ unwrapElement: { type: Boolean, default: false }
8679
8716
  },
8680
8717
  setup(__props) {
8681
8718
  const props = __props;
@@ -8702,9 +8739,13 @@ const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
8702
8739
  exitDom.clear();
8703
8740
  });
8704
8741
  function exit(el, done) {
8705
- const state2 = mountedStates.get(el);
8742
+ let state2 = mountedStates.get(el);
8706
8743
  if (!state2) {
8707
- return done();
8744
+ if (!props.unwrapElement) {
8745
+ return done();
8746
+ }
8747
+ el = el.firstElementChild;
8748
+ state2 = mountedStates.get(el);
8708
8749
  }
8709
8750
  exitDom.set(el, true);
8710
8751
  removeDoneCallback(el);
@@ -8761,7 +8802,7 @@ const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
8761
8802
  };
8762
8803
  }
8763
8804
  });
8764
- const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
8805
+ const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
8765
8806
  ...{
8766
8807
  name: "MotionConfig",
8767
8808
  inheritAttrs: false
@@ -8823,7 +8864,7 @@ function moveItem([...arr], fromIndex, toIndex) {
8823
8864
  function useDefaultMotionValue(value, defaultValue = 0) {
8824
8865
  return isMotionValue(value) ? value : motionValue(defaultValue);
8825
8866
  }
8826
- const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
8867
+ const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
8827
8868
  ...{
8828
8869
  name: "ReorderGroup",
8829
8870
  inheritAttrs: false
@@ -8917,12 +8958,14 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
8917
8958
  order2.sort(compareMin);
8918
8959
  },
8919
8960
  updateOrder: (item, offset, velocity) => {
8961
+ var _a;
8920
8962
  if (isReordering)
8921
8963
  return;
8922
8964
  const newOrder = checkReorder(order2, item, offset, velocity);
8923
8965
  if (order2 !== newOrder) {
8924
8966
  isReordering = true;
8925
- props["onUpdate:values"](
8967
+ (_a = props["onUpdate:values"]) == null ? void 0 : _a.call(
8968
+ props,
8926
8969
  newOrder.map(getValue).filter((value) => props.values.includes(value))
8927
8970
  );
8928
8971
  }
@@ -8936,7 +8979,7 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
8936
8979
  };
8937
8980
  }
8938
8981
  return (_ctx, _cache) => {
8939
- return vue.openBlock(), vue.createBlock(vue.unref(_sfc_main$5), vue.normalizeProps(vue.guardReactiveProps(bindProps())), {
8982
+ return vue.openBlock(), vue.createBlock(vue.unref(_sfc_main$6), vue.normalizeProps(vue.guardReactiveProps(bindProps())), {
8940
8983
  default: vue.withCtx(() => [
8941
8984
  vue.renderSlot(_ctx.$slots, "default"),
8942
8985
  vue.createTextVNode(" " + vue.toDisplayString(warning2()), 1)
@@ -9146,7 +9189,7 @@ function useVelocity(value) {
9146
9189
  });
9147
9190
  return velocity;
9148
9191
  }
9149
- const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
9192
+ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
9150
9193
  ...{
9151
9194
  name: "ReorderItem",
9152
9195
  inheritAttrs: false
@@ -9249,7 +9292,7 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
9249
9292
  return axis.value;
9250
9293
  });
9251
9294
  return (_ctx, _cache) => {
9252
- return vue.openBlock(), vue.createBlock(vue.unref(_sfc_main$5), vue.mergeProps(bindProps(), {
9295
+ return vue.openBlock(), vue.createBlock(vue.unref(_sfc_main$6), vue.mergeProps(bindProps(), {
9253
9296
  drag: drag.value,
9254
9297
  "drag-snap-to-origin": true,
9255
9298
  onDrag: _cache[0] || (_cache[0] = (event, gesturePoint) => {
@@ -9268,12 +9311,33 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
9268
9311
  };
9269
9312
  }
9270
9313
  });
9271
- const ReorderGroup = _sfc_main$2;
9272
- const ReorderItem = _sfc_main$1;
9314
+ const ReorderGroup = _sfc_main$3;
9315
+ const ReorderItem = _sfc_main$2;
9273
9316
  const Reorder = {
9274
9317
  Group: ReorderGroup,
9275
9318
  Item: ReorderItem
9276
9319
  };
9320
+ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
9321
+ __name: "RowValue",
9322
+ props: {
9323
+ value: {}
9324
+ },
9325
+ setup(__props) {
9326
+ const props = __props;
9327
+ const instance = vue.getCurrentInstance().proxy;
9328
+ vue.watchEffect((cleanup) => {
9329
+ const unSub = props.value.on("change", (value) => {
9330
+ if (instance.$el) {
9331
+ instance.$el.textContent = value;
9332
+ }
9333
+ });
9334
+ cleanup(unSub);
9335
+ });
9336
+ return (_ctx, _cache) => {
9337
+ return vue.toDisplayString(_ctx.value.get());
9338
+ };
9339
+ }
9340
+ });
9277
9341
  function useForceUpdate() {
9278
9342
  const key = vue.ref(0);
9279
9343
  function forceUpdate() {
@@ -9303,6 +9367,7 @@ function nodeGroup() {
9303
9367
  unsubscribe();
9304
9368
  subscriptions.delete(node);
9305
9369
  }
9370
+ dirtyAll();
9306
9371
  },
9307
9372
  dirty: dirtyAll
9308
9373
  };
@@ -9537,14 +9602,15 @@ class DragControls {
9537
9602
  }
9538
9603
  const createDragControls = () => new DragControls();
9539
9604
  const useDragControls = createDragControls;
9540
- exports.AnimatePresence = _sfc_main$4;
9605
+ exports.AnimatePresence = _sfc_main$5;
9541
9606
  exports.LayoutGroup = _sfc_main;
9542
- exports.Motion = _sfc_main$5;
9543
- exports.MotionConfig = _sfc_main$3;
9607
+ exports.Motion = _sfc_main$6;
9608
+ exports.MotionConfig = _sfc_main$4;
9544
9609
  exports.MotionValue = MotionValue;
9545
9610
  exports.Reorder = Reorder;
9546
9611
  exports.ReorderGroup = ReorderGroup;
9547
9612
  exports.ReorderItem = ReorderItem;
9613
+ exports.RowValue = _sfc_main$1;
9548
9614
  exports.animate = animate;
9549
9615
  exports.animateMini = animateMini;
9550
9616
  exports.anticipate = anticipate;
@@ -0,0 +1,16 @@
1
+ import { MotionValue } from 'framer-motion/dom';
2
+ declare const _default: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
3
+ props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps & Readonly<import('vue').ExtractPropTypes<{}>>, never>, never> & {
4
+ value: MotionValue<T>;
5
+ }> & import('vue').PublicProps;
6
+ expose(exposed: import('vue').ShallowUnwrapRef<{}>): void;
7
+ attrs: any;
8
+ slots: {};
9
+ emit: {};
10
+ }>) => import('vue').VNode & {
11
+ __ctx?: Awaited<typeof __VLS_setup>;
12
+ };
13
+ export default _default;
14
+ type __VLS_PrettifyLocal<T> = {
15
+ [K in keyof T]: T[K];
16
+ } & {};
@@ -0,0 +1,25 @@
1
+ import { defineComponent, getCurrentInstance, watchEffect, toDisplayString } from "vue";
2
+ const _sfc_main = /* @__PURE__ */ defineComponent({
3
+ __name: "RowValue",
4
+ props: {
5
+ value: {}
6
+ },
7
+ setup(__props) {
8
+ const props = __props;
9
+ const instance = getCurrentInstance().proxy;
10
+ watchEffect((cleanup) => {
11
+ const unSub = props.value.on("change", (value) => {
12
+ if (instance.$el) {
13
+ instance.$el.textContent = value;
14
+ }
15
+ });
16
+ cleanup(unSub);
17
+ });
18
+ return (_ctx, _cache) => {
19
+ return toDisplayString(_ctx.value.get());
20
+ };
21
+ }
22
+ });
23
+ export {
24
+ _sfc_main as default
25
+ };
@@ -0,0 +1,4 @@
1
+ import _sfc_main from "./RowValue.vue.mjs";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -11,14 +11,17 @@ declare const __VLS_component: import('vue').DefineComponent<__VLS_WithDefaults<
11
11
  mode: string;
12
12
  initial: boolean;
13
13
  multiple: boolean;
14
+ unwrapElement: boolean;
14
15
  }>, {}, unknown, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<AnimatePresenceProps>, {
15
16
  mode: string;
16
17
  initial: boolean;
17
18
  multiple: boolean;
19
+ unwrapElement: boolean;
18
20
  }>>>, {
19
21
  initial: boolean;
20
22
  mode: "wait" | "popLayout" | "sync";
21
23
  multiple: boolean;
24
+ unwrapElement: boolean;
22
25
  }, {}>;
23
26
  declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
24
27
  export default _default;
@@ -15,7 +15,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
15
15
  multiple: { type: Boolean, default: false },
16
16
  as: {},
17
17
  custom: {},
18
- onExitComplete: {}
18
+ onExitComplete: {},
19
+ unwrapElement: { type: Boolean, default: false }
19
20
  },
20
21
  setup(__props) {
21
22
  const props = __props;
@@ -42,9 +43,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
42
43
  exitDom.clear();
43
44
  });
44
45
  function exit(el, done) {
45
- const state = mountedStates.get(el);
46
+ let state = mountedStates.get(el);
46
47
  if (!state) {
47
- return done();
48
+ if (!props.unwrapElement) {
49
+ return done();
50
+ }
51
+ el = el.firstElementChild;
52
+ state = mountedStates.get(el);
48
53
  }
49
54
  exitDom.set(el, true);
50
55
  removeDoneCallback(el);
@@ -5,4 +5,5 @@ export interface AnimatePresenceProps {
5
5
  as?: string;
6
6
  custom?: any;
7
7
  onExitComplete?: VoidFunction;
8
+ unwrapElement?: boolean;
8
9
  }
@@ -20,6 +20,7 @@ function nodeGroup() {
20
20
  unsubscribe();
21
21
  subscriptions.delete(node);
22
22
  }
23
+ dirtyAll();
23
24
  },
24
25
  dirty: dirtyAll
25
26
  };
@@ -2,3 +2,4 @@ export { Motion, motion, type MotionProps } from './motion';
2
2
  export * from './animate-presence';
3
3
  export * from './motion-config';
4
4
  export * from './reorder';
5
+ export { default as RowValue } from './RowValue';
@@ -97,12 +97,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
97
97
  order.sort(compareMin);
98
98
  },
99
99
  updateOrder: (item, offset, velocity) => {
100
+ var _a;
100
101
  if (isReordering)
101
102
  return;
102
103
  const newOrder = checkReorder(order, item, offset, velocity);
103
104
  if (order !== newOrder) {
104
105
  isReordering = true;
105
- props["onUpdate:values"](
106
+ (_a = props["onUpdate:values"]) == null ? void 0 : _a.call(
107
+ props,
106
108
  newOrder.map(getValue).filter((value) => props.values.includes(value))
107
109
  );
108
110
  }
@@ -5,7 +5,6 @@ export declare class LayoutFeature extends Feature {
5
5
  beforeUpdate(): void;
6
6
  update(): void;
7
7
  didUpdate(): void;
8
- beforeMount(): void;
9
8
  mount(): void;
10
9
  beforeUnmount(): void;
11
10
  unmount(): void;
@@ -18,19 +18,18 @@ class LayoutFeature extends Feature {
18
18
  if (this.state.options.layout || this.state.options.layoutId)
19
19
  (_b = (_a = this.state.visualElement.projection) == null ? void 0 : _a.root) == null ? void 0 : _b.didUpdate();
20
20
  }
21
- beforeMount() {
22
- }
23
21
  mount() {
24
22
  var _a;
25
23
  const options = this.state.options;
26
24
  const layoutGroup = this.state.options.layoutGroup;
27
- if (options.layout || options.layoutId) {
25
+ if (options.layout || options.layoutId || options.drag) {
28
26
  const projection = this.state.visualElement.projection;
29
27
  if (projection) {
28
+ projection.promote();
30
29
  (_a = layoutGroup == null ? void 0 : layoutGroup.group) == null ? void 0 : _a.add(projection);
31
30
  }
32
- globalProjectionState.hasEverUpdated = true;
33
31
  this.didUpdate();
32
+ globalProjectionState.hasEverUpdated = true;
34
33
  }
35
34
  }
36
35
  beforeUnmount() {
@@ -48,9 +47,11 @@ class LayoutFeature extends Feature {
48
47
  unmount() {
49
48
  const layoutGroup = this.state.options.layoutGroup;
50
49
  const projection = this.state.visualElement.projection;
51
- if ((layoutGroup == null ? void 0 : layoutGroup.group) && projection)
50
+ if ((layoutGroup == null ? void 0 : layoutGroup.group) && projection) {
52
51
  layoutGroup.group.remove(projection);
53
- this.didUpdate();
52
+ } else {
53
+ this.didUpdate();
54
+ }
54
55
  }
55
56
  }
56
57
  export {
package/dist/es/index.mjs CHANGED
@@ -4,8 +4,9 @@ import { injectLayoutGroup, injectMotion, provideLayoutGroup, provideMotion } fr
4
4
  import { components, utilities } from "./constants/index.mjs";
5
5
  import { useDragControls } from "./features/gestures/drag/use-drag-controls.mjs";
6
6
  import { default as default3 } from "./components/motion/Motion.vue.mjs";
7
- import { default as default4 } from "./components/animate-presence/AnimatePresence.vue.mjs";
8
- import { default as default5 } from "./components/motion-config/MotionConfig.vue.mjs";
7
+ import { default as default4 } from "./components/RowValue.vue.mjs";
8
+ import { default as default5 } from "./components/animate-presence/AnimatePresence.vue.mjs";
9
+ import { default as default6 } from "./components/motion-config/MotionConfig.vue.mjs";
9
10
  import { MotionValue, motionValue, motionValue as motionValue2 } from "./external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/value/index.mjs";
10
11
  import { isDragActive } from "./external/.pnpm/motion-dom@11.16.4/external/motion-dom/dist/es/gestures/drag/state/is-active.mjs";
11
12
  import { invariant } from "./external/.pnpm/motion-utils@11.16.0/external/motion-utils/dist/es/errors.mjs";
@@ -60,14 +61,15 @@ import { useAnimationFrame } from "./utils/use-animation-frame.mjs";
60
61
  import { millisecondsToSeconds, secondsToMilliseconds } from "./utils/time-conversion.mjs";
61
62
  import { getContextWindow } from "./utils/get-context-window.mjs";
62
63
  export {
63
- default4 as AnimatePresence,
64
+ default5 as AnimatePresence,
64
65
  default2 as LayoutGroup,
65
66
  default3 as Motion,
66
- default5 as MotionConfig,
67
+ default6 as MotionConfig,
67
68
  MotionValue,
68
69
  Reorder,
69
70
  ReorderGroup,
70
71
  ReorderItem,
72
+ default4 as RowValue,
71
73
  animate,
72
74
  animateMini,
73
75
  anticipate,
@@ -3,7 +3,8 @@ import { DOMKeyframesDefinition, VisualElement } from 'framer-motion';
3
3
  import { StateType, animateUpdates } from './animate-updates';
4
4
  export declare const mountedStates: WeakMap<Element, MotionState>;
5
5
  /**
6
- * Core class that manages animation state and orchestrates animations
6
+ * Core class that manages animation state and orchestrates animations.
7
+ * Handles component lifecycle methods in the correct order based on component tree position.
7
8
  */
8
9
  export declare class MotionState {
9
10
  readonly id: string;
@@ -23,14 +24,13 @@ export declare class MotionState {
23
24
  private _context;
24
25
  get context(): MotionStateContext;
25
26
  private initTarget;
26
- get initial(): string | boolean | import('../types').Variant;
27
27
  updateOptions(): void;
28
28
  beforeMount(): void;
29
29
  mount(element: HTMLElement, options: Options, notAnimate?: boolean): void;
30
30
  beforeUnmount(): void;
31
31
  unmount(unMountChildren?: boolean): void;
32
32
  beforeUpdate(): void;
33
- update(options: Options, notAnimate?: boolean): void;
33
+ update(options: Options): void;
34
34
  setActive(name: StateType, isActive: boolean, isAnimate?: boolean): void;
35
35
  animateUpdates: typeof animateUpdates;
36
36
  isMounted(): boolean;
@@ -1,7 +1,6 @@
1
1
  import { invariant } from "hey-listen";
2
2
  import { visualElementStore } from "../external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/render/store.mjs";
3
- import { isDef } from "@vueuse/core";
4
- import { resolveVariant } from "./utils.mjs";
3
+ import { resolveVariant, isAnimateChanged } from "./utils.mjs";
5
4
  import { FeatureManager } from "../features/feature-manager.mjs";
6
5
  import { createVisualElement } from "./create-visual-element.mjs";
7
6
  import { doneCallbacks } from "../components/presence.mjs";
@@ -9,6 +8,7 @@ import { animateUpdates } from "./animate-updates.mjs";
9
8
  import { frame } from "../external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/frameloop/frame.mjs";
10
9
  const mountedStates = /* @__PURE__ */ new WeakMap();
11
10
  let id = 0;
11
+ const mountedLayoutIds = /* @__PURE__ */ new Set();
12
12
  class MotionState {
13
13
  constructor(options, parent) {
14
14
  var _a;
@@ -52,7 +52,7 @@ class MotionState {
52
52
  this.initTarget(initialVariantSource);
53
53
  this.featureManager = new FeatureManager(this);
54
54
  }
55
- // Get animation context, falling back to parent context
55
+ // Get animation context, falling back to parent context for inheritance
56
56
  get context() {
57
57
  if (!this._context) {
58
58
  const handler = {
@@ -73,10 +73,6 @@ class MotionState {
73
73
  }
74
74
  this.target = {};
75
75
  }
76
- // Get initial animation state
77
- get initial() {
78
- return isDef(this.options.initial) ? this.options.initial : this.context.initial;
79
- }
80
76
  // Update visual element with new options
81
77
  updateOptions() {
82
78
  this.visualElement.update({
@@ -89,10 +85,11 @@ class MotionState {
89
85
  isPresent: !doneCallbacks.has(this.element)
90
86
  });
91
87
  }
88
+ // Called before mounting, executes in parent-to-child order
92
89
  beforeMount() {
93
90
  this.featureManager.beforeMount();
94
91
  }
95
- // Mount motion state to DOM element
92
+ // Mount motion state to DOM element, handles parent-child relationships
96
93
  mount(element, options, notAnimate = false) {
97
94
  invariant(
98
95
  Boolean(element),
@@ -111,51 +108,66 @@ class MotionState {
111
108
  if (!notAnimate && this.options.animate) {
112
109
  this.animateUpdates();
113
110
  }
111
+ if (this.options.layoutId) {
112
+ mountedLayoutIds.add(this.options.layoutId);
113
+ frame.render(() => {
114
+ mountedLayoutIds.clear();
115
+ });
116
+ }
114
117
  }
118
+ // Called before unmounting, executes in child-to-parent order
115
119
  beforeUnmount() {
116
120
  this.featureManager.beforeUnmount();
117
121
  }
118
122
  // Unmount motion state and optionally unmount children
123
+ // Handles unmounting in the correct order based on component tree
119
124
  unmount(unMountChildren = false) {
120
- var _a, _b, _c;
121
- mountedStates.delete(this.element);
122
- this.featureManager.unmount();
123
- if (unMountChildren) {
124
- frame.render(() => {
125
- var _a2;
126
- (_a2 = this.visualElement) == null ? void 0 : _a2.unmount();
125
+ const shouldDelay = this.options.layoutId && !mountedLayoutIds.has(this.options.layoutId);
126
+ const unmount = () => {
127
+ var _a, _b, _c;
128
+ mountedStates.delete(this.element);
129
+ this.featureManager.unmount();
130
+ if (unMountChildren && !shouldDelay) {
131
+ frame.render(() => {
132
+ var _a2;
133
+ (_a2 = this.visualElement) == null ? void 0 : _a2.unmount();
134
+ });
135
+ } else {
136
+ (_a = this.visualElement) == null ? void 0 : _a.unmount();
137
+ }
138
+ if (unMountChildren) {
139
+ const unmountChild = (child) => {
140
+ var _a2;
141
+ child.unmount(true);
142
+ (_a2 = child.children) == null ? void 0 : _a2.forEach(unmountChild);
143
+ };
144
+ Array.from(this.children).forEach(unmountChild);
145
+ }
146
+ (_c = (_b = this.parent) == null ? void 0 : _b.children) == null ? void 0 : _c.delete(this);
147
+ };
148
+ if (shouldDelay) {
149
+ Promise.resolve().then(() => {
150
+ unmount();
127
151
  });
128
152
  } else {
129
- (_a = this.visualElement) == null ? void 0 : _a.unmount();
130
- }
131
- if (unMountChildren) {
132
- const unmountChild = (child) => {
133
- var _a2;
134
- child.unmount(true);
135
- (_a2 = child.children) == null ? void 0 : _a2.forEach(unmountChild);
136
- };
137
- Array.from(this.children).forEach(unmountChild);
153
+ unmount();
138
154
  }
139
- (_c = (_b = this.parent) == null ? void 0 : _b.children) == null ? void 0 : _c.delete(this);
140
155
  }
156
+ // Called before updating, executes in parent-to-child order
141
157
  beforeUpdate() {
142
158
  this.featureManager.beforeUpdate();
143
159
  }
144
160
  // Update motion state with new options
145
- update(options, notAnimate = false) {
146
- const prevAnimate = JSON.stringify(this.options.animate);
161
+ update(options) {
162
+ const hasAnimateChange = isAnimateChanged(this.options, options);
147
163
  this.options = options;
148
- let hasAnimateChange = false;
149
- if (prevAnimate !== JSON.stringify(options.animate)) {
150
- hasAnimateChange = true;
151
- }
152
164
  this.updateOptions();
153
165
  this.featureManager.update();
154
- if (hasAnimateChange && !notAnimate) {
166
+ if (hasAnimateChange) {
155
167
  this.animateUpdates();
156
168
  }
157
169
  }
158
- // Set animation state active status
170
+ // Set animation state active status and propagate to children
159
171
  setActive(name, isActive, isAnimate = true) {
160
172
  var _a;
161
173
  if (!this.element || this.activeStates[name] === isActive)
@@ -176,10 +188,12 @@ class MotionState {
176
188
  getOptions() {
177
189
  return this.options;
178
190
  }
191
+ // Called before layout updates to prepare for changes
179
192
  willUpdate(label) {
180
193
  var _a;
181
- if (this.options.layout || this.options.layoutId)
194
+ if (this.options.layout || this.options.layoutId) {
182
195
  (_a = this.visualElement.projection) == null ? void 0 : _a.willUpdate();
196
+ }
183
197
  }
184
198
  }
185
199
  export {
@@ -15,4 +15,5 @@ export declare const svgElements: readonly ["animate", "circle", "defs", "desc",
15
15
  type UnionStringArray<T extends Readonly<string[]>> = T[number];
16
16
  export type SVGElements = UnionStringArray<typeof svgElements>;
17
17
  export declare function isSVGElement(as: ElementType): as is SVGElements;
18
+ export declare function isAnimateChanged(oldOptions: Options, newOptions: Options): boolean;
18
19
  export {};
@@ -94,9 +94,30 @@ const svgElementSet = new Set(svgElements);
94
94
  function isSVGElement(as) {
95
95
  return svgElementSet.has(as);
96
96
  }
97
+ function isAnimateChanged(oldOptions, newOptions) {
98
+ const oldAnimate = oldOptions.animate;
99
+ const newAnimate = newOptions.animate;
100
+ if (oldAnimate === newAnimate)
101
+ return false;
102
+ if (!oldAnimate || !newAnimate)
103
+ return true;
104
+ if (typeof oldAnimate === "object" || typeof newAnimate === "object") {
105
+ const oldKeys = Object.keys(oldAnimate);
106
+ const newKeys = Object.keys(newAnimate);
107
+ if (oldKeys.length !== newKeys.length)
108
+ return true;
109
+ return oldKeys.some((key) => {
110
+ const oldVal = oldAnimate[key];
111
+ const newVal = newAnimate[key];
112
+ return oldVal !== newVal;
113
+ });
114
+ }
115
+ return oldAnimate !== newAnimate;
116
+ }
97
117
  export {
98
118
  getOptions,
99
119
  hasChanged,
120
+ isAnimateChanged,
100
121
  isCssVar,
101
122
  isNumber,
102
123
  isSVGElement,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "motion-v",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "",
5
5
  "author": "",
6
6
  "license": "MIT",
@@ -71,7 +71,7 @@
71
71
  "rimraf": "^6.0.1",
72
72
  "vite": "^5.4.8",
73
73
  "vite-plugin-dts": "^4.2.4",
74
- "vitest": "^1.4.0",
74
+ "vitest": "^1.6.1",
75
75
  "vue": "3.4.38"
76
76
  },
77
77
  "scripts": {