motion-v 0.5.0 → 0.5.2-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/cjs/index.js +185 -111
  2. package/dist/es/components/AnimatePresence.vue.mjs +1 -4
  3. package/dist/es/components/LayoutGroup.vue.mjs +12 -4
  4. package/dist/es/components/Motion.vue.mjs +33 -16
  5. package/dist/es/components/context.mjs +1 -9
  6. package/dist/es/components/motion-config/MotionConfig.vue.mjs +30 -0
  7. package/dist/es/components/motion-config/MotionConfig.vue2.mjs +4 -0
  8. package/dist/es/components/motion-config/context.mjs +17 -0
  9. package/dist/es/components/use-layout-group.mjs +8 -6
  10. package/dist/es/components/use-pop-layout.mjs +5 -0
  11. package/dist/es/constants/index.mjs +2 -1
  12. package/dist/es/features/layout/layout.mjs +7 -9
  13. package/dist/es/features/layout/projection.mjs +17 -1
  14. package/dist/es/index.mjs +8 -3
  15. package/dist/es/state/animate-variants-children.mjs +1 -1
  16. package/dist/es/state/motion-state.mjs +4 -2
  17. package/dist/es/value/use-spring.mjs +2 -3
  18. package/dist/src/components/LayoutGroup.d.ts +4 -1
  19. package/dist/src/components/Motion.d.ts +1 -0
  20. package/dist/src/components/context.d.ts +0 -3
  21. package/dist/src/components/motion-config/MotionConfig.d.ts +39 -0
  22. package/dist/src/components/motion-config/context.d.ts +11 -0
  23. package/dist/src/components/motion-config/index.d.ts +2 -0
  24. package/dist/src/components/motion-config/types.d.ts +14 -0
  25. package/dist/src/components/use-layout-group.d.ts +4 -1
  26. package/dist/src/components/use-slot-change-index.d.ts +1 -0
  27. package/dist/src/features/gestures/drag/types.d.ts +5 -3
  28. package/dist/src/features/gestures/types.d.ts +0 -5
  29. package/dist/src/features/layout/projection.d.ts +1 -0
  30. package/dist/src/features/layout/types.d.ts +1 -0
  31. package/dist/src/index.d.ts +2 -0
  32. package/dist/src/types/state.d.ts +2 -0
  33. package/package.json +1 -1
package/dist/cjs/index.js CHANGED
@@ -4811,12 +4811,6 @@ function getContextWindow({ current }) {
4811
4811
  }
4812
4812
  const [injectMotion, provideMotion] = createContext("Motion");
4813
4813
  const [injectLayoutGroup, provideLayoutGroup] = createContext("LayoutGroup");
4814
- function shouldInheritGroup(inherit) {
4815
- return inherit === true;
4816
- }
4817
- function shouldInheritId(inherit) {
4818
- return shouldInheritGroup(inherit === true) || inherit === "id";
4819
- }
4820
4814
  function resolveVariant(definition, variants, custom) {
4821
4815
  if (typeof definition === "object") {
4822
4816
  return definition;
@@ -6212,9 +6206,8 @@ class LayoutFeature extends Feature {
6212
6206
  (_a = this.state.visualElement.projection) == null ? void 0 : _a.willUpdate();
6213
6207
  }
6214
6208
  update() {
6215
- var _a, _b;
6216
- (_a = this.state.visualElement.projection) == null ? void 0 : _a.setOptions(this.state.options);
6217
- (_b = this.state.visualElement.projection) == null ? void 0 : _b.root.didUpdate();
6209
+ var _a;
6210
+ (_a = this.state.visualElement.projection) == null ? void 0 : _a.root.didUpdate();
6218
6211
  }
6219
6212
  beforeMount() {
6220
6213
  }
@@ -6232,16 +6225,15 @@ class LayoutFeature extends Feature {
6232
6225
  }
6233
6226
  }
6234
6227
  beforeUnmount() {
6235
- if (this.state.visualElement.projection) {
6236
- this.state.visualElement.projection.willUpdate();
6237
- }
6238
6228
  }
6239
6229
  unmount() {
6240
- if (this.state.visualElement.projection) {
6241
- this.state.visualElement.projection.unmount();
6230
+ const projection = this.state.visualElement.projection;
6231
+ if (projection) {
6232
+ projection.root.didUpdate();
6233
+ projection.finishAnimation();
6242
6234
  const layoutGroup = this.state.options.layoutGroup;
6243
6235
  if (layoutGroup == null ? void 0 : layoutGroup.group)
6244
- layoutGroup.group.remove(this.state.visualElement.projection);
6236
+ layoutGroup.group.remove(projection);
6245
6237
  }
6246
6238
  }
6247
6239
  }
@@ -7730,12 +7722,28 @@ class ProjectionFeature extends Feature {
7730
7722
  animationType: typeof options.layout === "string" ? options.layout : "both",
7731
7723
  // initialPromotionConfig
7732
7724
  layoutRoot: options.layoutRoot,
7733
- layoutScroll: options.layoutScroll
7725
+ layoutScroll: options.layoutScroll,
7726
+ crossfade: options.crossfade
7734
7727
  });
7735
7728
  }
7736
7729
  beforeMount() {
7737
7730
  this.initProjection();
7738
7731
  }
7732
+ update() {
7733
+ const options = this.state.options;
7734
+ this.state.visualElement.projection.setOptions({
7735
+ layout: options.layout,
7736
+ layoutId: options.layoutId,
7737
+ // TODO: drag
7738
+ alwaysMeasureLayout: false,
7739
+ visualElement: this.state.visualElement,
7740
+ animationType: typeof options.layout === "string" ? options.layout : "both",
7741
+ // initialPromotionConfig
7742
+ layoutRoot: options.layoutRoot,
7743
+ layoutScroll: options.layoutScroll,
7744
+ crossfade: options.crossfade
7745
+ });
7746
+ }
7739
7747
  mount() {
7740
7748
  var _a;
7741
7749
  (_a = this.state.visualElement.projection) == null ? void 0 : _a.mount(this.state.element);
@@ -7828,7 +7836,7 @@ function animateVariantsChildren(state2, activeState) {
7828
7836
  for (const name in activeState) {
7829
7837
  childState.activeStates[name] = true;
7830
7838
  const { definition, transition } = activeState[name];
7831
- const { staggerChildren = 0, staggerDirection = 1, delayChildren = 0 } = transition;
7839
+ const { staggerChildren = 0, staggerDirection = 1, delayChildren = 0 } = transition || {};
7832
7840
  const maxStaggerDuration = (variantChildren.size - 1) * staggerChildren;
7833
7841
  const generateStaggerDuration = staggerDirection === 1 ? (i = 0) => i * staggerChildren : (i = 0) => maxStaggerDuration - i * staggerChildren;
7834
7842
  const variant = resolveVariant(
@@ -7910,7 +7918,8 @@ class MotionState {
7910
7918
  attrs: {}
7911
7919
  },
7912
7920
  latestValues: {}
7913
- }
7921
+ },
7922
+ reducedMotionConfig: options.motionConfig.reduceMotion
7914
7923
  });
7915
7924
  const initialVariantSource = options.initial === false ? "animate" : "initial";
7916
7925
  this.featureManager = new FeatureManager(this);
@@ -7940,7 +7949,8 @@ class MotionState {
7940
7949
  ...this.options,
7941
7950
  whileHover: this.options.hover,
7942
7951
  whileTap: this.options.press,
7943
- whileInView: this.options.inView
7952
+ whileInView: this.options.inView,
7953
+ reducedMotionConfig: this.options.motionConfig.reduceMotion
7944
7954
  }, {
7945
7955
  isPresent: !doneCallbacks.has(this.element)
7946
7956
  });
@@ -8121,7 +8131,16 @@ function getMotionElement(el) {
8121
8131
  return getMotionElement(el.nextSibling);
8122
8132
  return el;
8123
8133
  }
8124
- const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
8134
+ const defaultConfig = {
8135
+ reduceMotion: "never",
8136
+ transition: void 0,
8137
+ nonce: void 0
8138
+ };
8139
+ const [injectMotionConfig, provideMotionConfig] = createContext("MotionConfig");
8140
+ function useMotionConfig() {
8141
+ return injectMotionConfig(vue.computed(() => defaultConfig));
8142
+ }
8143
+ const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
8125
8144
  ...{
8126
8145
  name: "Motion",
8127
8146
  inheritAttrs: false
@@ -8130,6 +8149,7 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
8130
8149
  props: /* @__PURE__ */ vue.mergeDefaults({
8131
8150
  as: {},
8132
8151
  asChild: { type: Boolean },
8152
+ whileDrag: {},
8133
8153
  custom: {},
8134
8154
  initial: { type: [String, Object, Boolean] },
8135
8155
  animate: {},
@@ -8139,11 +8159,13 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
8139
8159
  transformTemplate: { type: Function },
8140
8160
  transition: {},
8141
8161
  layoutGroup: {},
8162
+ motionConfig: {},
8142
8163
  layout: { type: [Boolean, String] },
8143
8164
  layoutId: {},
8144
8165
  layoutScroll: { type: Boolean },
8145
8166
  layoutRoot: { type: Boolean },
8146
8167
  "data-framer-portal-id": {},
8168
+ crossfade: { type: Boolean },
8147
8169
  globalPressTarget: { type: Boolean },
8148
8170
  press: {},
8149
8171
  onPressStart: { type: Function },
@@ -8188,7 +8210,10 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
8188
8210
  layoutScroll: false,
8189
8211
  layoutRoot: false,
8190
8212
  dragListener: true,
8191
- dragElastic: 0.2
8213
+ dragElastic: 0.2,
8214
+ dragMomentum: true,
8215
+ whileDrag: void 0,
8216
+ crossfade: void 0
8192
8217
  }),
8193
8218
  setup(__props) {
8194
8219
  const props = __props;
@@ -8196,11 +8221,13 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
8196
8221
  const parentState = injectMotion(null);
8197
8222
  const attrs = vue.useAttrs();
8198
8223
  const layoutGroup = injectLayoutGroup({});
8224
+ const config = useMotionConfig();
8199
8225
  const state2 = new MotionState(
8200
8226
  {
8201
8227
  ...attrs,
8202
8228
  ...props,
8203
- layoutGroup
8229
+ layoutGroup,
8230
+ motionConfig: config.value
8204
8231
  },
8205
8232
  parentState
8206
8233
  );
@@ -8213,24 +8240,24 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
8213
8240
  state2.mount(getMotionElement(instance.$el), {
8214
8241
  ...attrs,
8215
8242
  ...props,
8243
+ transition: props.transition ?? config.value.transition,
8216
8244
  layoutGroup,
8245
+ motionConfig: config.value,
8217
8246
  initial: presenceInitial.value === false ? presenceInitial.value : props.initial === true ? void 0 : props.initial
8218
8247
  });
8219
8248
  });
8220
- vue.onBeforeUnmount(() => {
8221
- state2.beforeUnmount();
8222
- });
8249
+ vue.onBeforeUnmount(() => state2.beforeUnmount());
8223
8250
  vue.onUnmounted(() => {
8224
8251
  if (safeUnmount(getMotionElement(instance.$el)))
8225
8252
  state2.unmount();
8226
8253
  });
8227
- vue.onBeforeUpdate(() => {
8228
- state2.beforeUpdate();
8229
- });
8254
+ vue.onBeforeUpdate(() => state2.beforeUpdate());
8230
8255
  vue.onUpdated(() => {
8231
8256
  state2.update({
8232
8257
  ...attrs,
8233
8258
  ...props,
8259
+ transition: props.transition ?? config.value.transition,
8260
+ motionConfig: config.value,
8234
8261
  initial: presenceInitial.value === false ? presenceInitial.value : props.initial === true ? void 0 : props.initial
8235
8262
  });
8236
8263
  });
@@ -8248,94 +8275,42 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
8248
8275
  if (isSVG) {
8249
8276
  const { attributes, style: style2 } = convertSvgStyleToAttributes(state2.target);
8250
8277
  Object.assign(attrsProps, attributes);
8251
- Object.assign(styleProps, style2, props.style);
8278
+ Object.assign(styleProps, style2);
8252
8279
  }
8253
8280
  if (!state2.isMounted()) {
8254
- Object.assign(styleProps, state2.target, props.style);
8281
+ Object.assign(styleProps, state2.target);
8282
+ }
8283
+ if (props.drag && props.dragListener !== false) {
8284
+ Object.assign(styleProps, {
8285
+ userSelect: "none",
8286
+ WebkitUserSelect: "none",
8287
+ WebkitTouchCallout: "none",
8288
+ touchAction: props.drag === true ? "none" : `pan-${props.drag === "x" ? "y" : "x"}`
8289
+ });
8255
8290
  }
8256
- styleProps = createStyles(styleProps);
8291
+ styleProps = createStyles({
8292
+ ...styleProps,
8293
+ ...props.style
8294
+ });
8257
8295
  attrsProps.style = styleProps;
8258
8296
  return attrsProps;
8259
8297
  }
8260
8298
  return (_ctx, _cache) => {
8261
- var _a, _b;
8262
8299
  return vue.openBlock(), vue.createBlock(vue.unref(Primitive), vue.mergeProps({
8263
8300
  as: _ctx.as,
8264
8301
  "as-child": _ctx.asChild
8265
- }, getProps(), {
8266
- "data-layout-group-key": (_b = (_a = vue.unref(layoutGroup)) == null ? void 0 : _a.key) == null ? void 0 : _b.value
8267
- }), {
8302
+ }, getProps()), {
8268
8303
  default: vue.withCtx(() => [
8269
8304
  vue.renderSlot(_ctx.$slots, "default")
8270
8305
  ]),
8271
8306
  _: 3
8272
- }, 16, ["as", "as-child", "data-layout-group-key"]);
8307
+ }, 16, ["as", "as-child"]);
8273
8308
  };
8274
8309
  }
8275
8310
  });
8276
- function useForceUpdate() {
8277
- const key = vue.ref(0);
8278
- function forceUpdate() {
8279
- key.value++;
8280
- }
8281
- return [forceUpdate, key];
8282
- }
8283
- function notify(node) {
8284
- return !node.isLayoutDirty && node.willUpdate(false);
8285
- }
8286
- function nodeGroup() {
8287
- const nodes = /* @__PURE__ */ new Set();
8288
- const subscriptions = /* @__PURE__ */ new WeakMap();
8289
- const dirtyAll = () => nodes.forEach(notify);
8290
- return {
8291
- add: (node) => {
8292
- nodes.add(node);
8293
- subscriptions.set(
8294
- node,
8295
- node.addEventListener("willUpdate", dirtyAll)
8296
- );
8297
- },
8298
- remove: (node) => {
8299
- nodes.delete(node);
8300
- const unsubscribe = subscriptions.get(node);
8301
- if (unsubscribe) {
8302
- unsubscribe();
8303
- subscriptions.delete(node);
8304
- }
8305
- dirtyAll();
8306
- },
8307
- dirty: dirtyAll
8308
- };
8309
- }
8310
- function useLayoutGroup(props) {
8311
- const parentGroup = injectLayoutGroup(null);
8312
- const [forceRender, key] = useForceUpdate();
8313
- const context = {
8314
- id: getGroupId(props, parentGroup),
8315
- group: getGroup(props, parentGroup),
8316
- forceRender,
8317
- key
8318
- };
8319
- vue.watch(key, () => {
8320
- context.id = getGroupId(props, parentGroup);
8321
- });
8322
- provideLayoutGroup(context);
8323
- return context;
8324
- }
8325
- function getGroupId(props, parentGroup) {
8326
- const shouldInherit = props.inherit === true || props.inherit === "id";
8327
- const parentId = parentGroup == null ? void 0 : parentGroup.id;
8328
- if (shouldInherit && parentId) {
8329
- return props.id ? `${parentId}-${props.id}` : parentId;
8330
- }
8331
- return props.id;
8332
- }
8333
- function getGroup(props, parentGroup) {
8334
- const shouldInherit = props.inherit === true || props.inherit === "group";
8335
- return shouldInherit ? (parentGroup == null ? void 0 : parentGroup.group) || nodeGroup() : nodeGroup();
8336
- }
8337
8311
  function usePopLayout(props) {
8338
8312
  const styles = /* @__PURE__ */ new WeakMap();
8313
+ const config = useMotionConfig();
8339
8314
  function addPopStyle(state2) {
8340
8315
  if (props.mode !== "popLayout")
8341
8316
  return;
@@ -8347,6 +8322,9 @@ function usePopLayout(props) {
8347
8322
  };
8348
8323
  state2.element.dataset.motionPopId = state2.id;
8349
8324
  const style2 = document.createElement("style");
8325
+ if (config.value.nonce) {
8326
+ style2.nonce = config.value.nonce;
8327
+ }
8350
8328
  styles.set(state2, style2);
8351
8329
  document.head.appendChild(style2);
8352
8330
  style2.textContent = `
@@ -8378,7 +8356,7 @@ function usePopLayout(props) {
8378
8356
  removePopStyle
8379
8357
  };
8380
8358
  }
8381
- const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
8359
+ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
8382
8360
  ...{
8383
8361
  name: "AnimatePresence",
8384
8362
  inheritAttrs: true
@@ -8407,7 +8385,6 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
8407
8385
  removeDoneCallback(el);
8408
8386
  state2.setActive("exit", false);
8409
8387
  }
8410
- const layoutGroup = useLayoutGroup(props);
8411
8388
  const { addPopStyle, removePopStyle } = usePopLayout(props);
8412
8389
  function exit(el, done) {
8413
8390
  const state2 = mountedStates.get(el);
@@ -8417,12 +8394,11 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
8417
8394
  removeDoneCallback(el);
8418
8395
  addPopStyle(state2);
8419
8396
  function doneCallback(e) {
8420
- var _a, _b, _c;
8397
+ var _a, _b;
8421
8398
  removePopStyle(state2);
8422
8399
  if ((_a = e == null ? void 0 : e.detail) == null ? void 0 : _a.isExit) {
8423
8400
  removeDoneCallback(el);
8424
8401
  (_b = state2.visualElement.projection) == null ? void 0 : _b.willUpdate();
8425
- (_c = layoutGroup.forceRender) == null ? void 0 : _c.call(layoutGroup);
8426
8402
  done();
8427
8403
  if (!el.isConnected) {
8428
8404
  state2.unmount();
@@ -8449,7 +8425,70 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
8449
8425
  };
8450
8426
  }
8451
8427
  });
8452
- const _sfc_main = /* @__PURE__ */ vue.defineComponent({
8428
+ function useForceUpdate() {
8429
+ const key = vue.ref(0);
8430
+ function forceUpdate() {
8431
+ key.value++;
8432
+ }
8433
+ return [forceUpdate, key];
8434
+ }
8435
+ function notify(node) {
8436
+ return !node.isLayoutDirty && node.willUpdate(false);
8437
+ }
8438
+ function nodeGroup() {
8439
+ const nodes = /* @__PURE__ */ new Set();
8440
+ const subscriptions = /* @__PURE__ */ new WeakMap();
8441
+ const dirtyAll = () => nodes.forEach(notify);
8442
+ return {
8443
+ add: (node) => {
8444
+ nodes.add(node);
8445
+ subscriptions.set(
8446
+ node,
8447
+ node.addEventListener("willUpdate", dirtyAll)
8448
+ );
8449
+ },
8450
+ remove: (node) => {
8451
+ nodes.delete(node);
8452
+ const unsubscribe = subscriptions.get(node);
8453
+ if (unsubscribe) {
8454
+ unsubscribe();
8455
+ subscriptions.delete(node);
8456
+ }
8457
+ dirtyAll();
8458
+ },
8459
+ dirty: dirtyAll
8460
+ };
8461
+ }
8462
+ function useLayoutGroupProvider(props) {
8463
+ const parentGroup = injectLayoutGroup(null);
8464
+ const [forceRender, key] = useForceUpdate();
8465
+ const context = {
8466
+ id: getGroupId(props, parentGroup),
8467
+ group: getGroup(props, parentGroup),
8468
+ forceRender,
8469
+ key
8470
+ };
8471
+ provideLayoutGroup(context);
8472
+ return context;
8473
+ }
8474
+ function useLayoutGroup() {
8475
+ const { forceRender } = injectLayoutGroup({ forceRender: () => {
8476
+ } });
8477
+ return { forceRender };
8478
+ }
8479
+ function getGroupId(props, parentGroup) {
8480
+ const shouldInherit = props.inherit === true || props.inherit === "id";
8481
+ const parentId = parentGroup == null ? void 0 : parentGroup.id;
8482
+ if (shouldInherit && parentId) {
8483
+ return props.id ? `${parentId}-${props.id}` : parentId;
8484
+ }
8485
+ return props.id;
8486
+ }
8487
+ function getGroup(props, parentGroup) {
8488
+ const shouldInherit = props.inherit === true || props.inherit === "group";
8489
+ return shouldInherit ? (parentGroup == null ? void 0 : parentGroup.group) || nodeGroup() : nodeGroup();
8490
+ }
8491
+ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
8453
8492
  __name: "LayoutGroup",
8454
8493
  props: {
8455
8494
  id: {},
@@ -8457,7 +8496,40 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
8457
8496
  },
8458
8497
  setup(__props) {
8459
8498
  const props = __props;
8460
- useLayoutGroup(props);
8499
+ const { forceRender, key, group } = useLayoutGroupProvider(props);
8500
+ vue.onUpdated(() => {
8501
+ });
8502
+ vue.onBeforeUpdate(() => {
8503
+ group.dirty();
8504
+ });
8505
+ return (_ctx, _cache) => {
8506
+ return vue.renderSlot(_ctx.$slots, "default", {
8507
+ renderKey: vue.unref(key),
8508
+ forceRender: vue.unref(forceRender)
8509
+ });
8510
+ };
8511
+ }
8512
+ });
8513
+ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
8514
+ ...{
8515
+ name: "MotionConfig",
8516
+ inheritAttrs: false
8517
+ },
8518
+ __name: "MotionConfig",
8519
+ props: {
8520
+ transition: {},
8521
+ reduceMotion: { default: defaultConfig.reduceMotion },
8522
+ nonce: {}
8523
+ },
8524
+ setup(__props) {
8525
+ const props = __props;
8526
+ const parentConfig = useMotionConfig();
8527
+ const config = vue.computed(() => ({
8528
+ transition: props.transition ?? parentConfig.value.transition,
8529
+ reduceMotion: props.reduceMotion ?? parentConfig.value.reduceMotion,
8530
+ nonce: props.nonce ?? parentConfig.value.nonce
8531
+ }));
8532
+ provideMotionConfig(config);
8461
8533
  return (_ctx, _cache) => {
8462
8534
  return vue.renderSlot(_ctx.$slots, "default");
8463
8535
  };
@@ -8586,13 +8658,12 @@ function useSpring(source, config = {}) {
8586
8658
  });
8587
8659
  };
8588
8660
  vue.watch(() => JSON.stringify(config), () => {
8589
- const cleanup = value.attach((v, set) => {
8661
+ value.attach((v, set) => {
8590
8662
  latestValue = v;
8591
8663
  latestSetter = set;
8592
8664
  frame.update(startAnimation);
8593
8665
  return value.get();
8594
8666
  }, stopAnimation);
8595
- vue.onBeforeUnmount(() => cleanup());
8596
8667
  }, { immediate: true });
8597
8668
  if (isMotionValue(source)) {
8598
8669
  source.on("change", (v) => {
@@ -8683,7 +8754,8 @@ const utilities = {
8683
8754
  "useAnimate",
8684
8755
  "useInView",
8685
8756
  "useAnimationFrame",
8686
- "useMotionValueEvent"
8757
+ "useMotionValueEvent",
8758
+ "useLayoutGroup"
8687
8759
  ]
8688
8760
  };
8689
8761
  function useAnimate() {
@@ -8716,9 +8788,10 @@ Object.defineProperty(exports, "isDragActive", {
8716
8788
  enumerable: true,
8717
8789
  get: () => motionDom.isDragActive
8718
8790
  });
8719
- exports.AnimatePresence = _sfc_main$1;
8720
- exports.LayoutGroup = _sfc_main;
8721
- exports.Motion = _sfc_main$2;
8791
+ exports.AnimatePresence = _sfc_main$2;
8792
+ exports.LayoutGroup = _sfc_main$1;
8793
+ exports.Motion = _sfc_main$3;
8794
+ exports.MotionConfig = _sfc_main;
8722
8795
  exports.MotionValue = MotionValue;
8723
8796
  exports.animate = animate;
8724
8797
  exports.animateMini = animateMini;
@@ -8762,12 +8835,11 @@ exports.pipe = pipe;
8762
8835
  exports.progress = progress$1;
8763
8836
  exports.provideLayoutGroup = provideLayoutGroup;
8764
8837
  exports.provideMotion = provideMotion;
8838
+ exports.provideMotionConfig = provideMotionConfig;
8765
8839
  exports.reverseEasing = reverseEasing;
8766
8840
  exports.scroll = scroll;
8767
8841
  exports.scrollInfo = scrollInfo;
8768
8842
  exports.secondsToMilliseconds = secondsToMilliseconds;
8769
- exports.shouldInheritGroup = shouldInheritGroup;
8770
- exports.shouldInheritId = shouldInheritId;
8771
8843
  exports.spring = spring;
8772
8844
  exports.stagger = stagger;
8773
8845
  exports.steps = steps;
@@ -8779,6 +8851,8 @@ exports.useAnimationFrame = useAnimationFrame;
8779
8851
  exports.useCombineMotionValues = useCombineMotionValues;
8780
8852
  exports.useComputed = useComputed;
8781
8853
  exports.useInView = useInView;
8854
+ exports.useLayoutGroup = useLayoutGroup;
8855
+ exports.useMotionConfig = useMotionConfig;
8782
8856
  exports.useMotionTemplate = useMotionTemplate;
8783
8857
  exports.useMotionValue = motionValue;
8784
8858
  exports.useMotionValueEvent = useMotionValueEvent;
@@ -1,7 +1,6 @@
1
1
  import { defineComponent, toRefs, openBlock, createBlock, resolveDynamicComponent, TransitionGroup, Transition, withCtx, renderSlot } from "vue";
2
2
  import { mountedStates } from "../state/motion-state.mjs";
3
3
  import { provideAnimatePresence, doneCallbacks, removeDoneCallback } from "./presence.mjs";
4
- import { useLayoutGroup } from "./use-layout-group.mjs";
5
4
  import { usePopLayout } from "./use-pop-layout.mjs";
6
5
  const _sfc_main = /* @__PURE__ */ defineComponent({
7
6
  ...{
@@ -32,7 +31,6 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
32
31
  removeDoneCallback(el);
33
32
  state.setActive("exit", false);
34
33
  }
35
- const layoutGroup = useLayoutGroup(props);
36
34
  const { addPopStyle, removePopStyle } = usePopLayout(props);
37
35
  function exit(el, done) {
38
36
  const state = mountedStates.get(el);
@@ -42,12 +40,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
42
40
  removeDoneCallback(el);
43
41
  addPopStyle(state);
44
42
  function doneCallback(e) {
45
- var _a, _b, _c;
43
+ var _a, _b;
46
44
  removePopStyle(state);
47
45
  if ((_a = e == null ? void 0 : e.detail) == null ? void 0 : _a.isExit) {
48
46
  removeDoneCallback(el);
49
47
  (_b = state.visualElement.projection) == null ? void 0 : _b.willUpdate();
50
- (_c = layoutGroup.forceRender) == null ? void 0 : _c.call(layoutGroup);
51
48
  done();
52
49
  if (!el.isConnected) {
53
50
  state.unmount();
@@ -1,5 +1,5 @@
1
- import { defineComponent, renderSlot } from "vue";
2
- import { useLayoutGroup } from "./use-layout-group.mjs";
1
+ import { defineComponent, onUpdated, 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,17 @@ 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
+ onUpdated(() => {
13
+ });
14
+ onBeforeUpdate(() => {
15
+ group.dirty();
16
+ });
12
17
  return (_ctx, _cache) => {
13
- return renderSlot(_ctx.$slots, "default");
18
+ return renderSlot(_ctx.$slots, "default", {
19
+ renderKey: unref(key),
20
+ forceRender: unref(forceRender)
21
+ });
14
22
  };
15
23
  }
16
24
  });
@@ -5,6 +5,7 @@ import { Primitive } from "./Primitive.mjs";
5
5
  import { MotionState } from "../state/motion-state.mjs";
6
6
  import { injectAnimatePresence } from "./presence.mjs";
7
7
  import { getMotionElement } 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,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
24
26
  transformTemplate: { type: Function },
25
27
  transition: {},
26
28
  layoutGroup: {},
29
+ motionConfig: {},
27
30
  layout: { type: [Boolean, String] },
28
31
  layoutId: {},
29
32
  layoutScroll: { type: Boolean },
30
33
  layoutRoot: { type: Boolean },
31
34
  "data-framer-portal-id": {},
35
+ crossfade: { type: Boolean },
32
36
  globalPressTarget: { type: Boolean },
33
37
  press: {},
34
38
  onPressStart: { type: Function },
@@ -73,7 +77,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
73
77
  layoutScroll: false,
74
78
  layoutRoot: false,
75
79
  dragListener: true,
76
- dragElastic: 0.2
80
+ dragElastic: 0.2,
81
+ dragMomentum: true,
82
+ whileDrag: void 0,
83
+ crossfade: void 0
77
84
  }),
78
85
  setup(__props) {
79
86
  const props = __props;
@@ -81,11 +88,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
81
88
  const parentState = injectMotion(null);
82
89
  const attrs = useAttrs();
83
90
  const layoutGroup = injectLayoutGroup({});
91
+ const config = useMotionConfig();
84
92
  const state = new MotionState(
85
93
  {
86
94
  ...attrs,
87
95
  ...props,
88
- layoutGroup
96
+ layoutGroup,
97
+ motionConfig: config.value
89
98
  },
90
99
  parentState
91
100
  );
@@ -98,24 +107,24 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
98
107
  state.mount(getMotionElement(instance.$el), {
99
108
  ...attrs,
100
109
  ...props,
110
+ transition: props.transition ?? config.value.transition,
101
111
  layoutGroup,
112
+ motionConfig: config.value,
102
113
  initial: presenceInitial.value === false ? presenceInitial.value : props.initial === true ? void 0 : props.initial
103
114
  });
104
115
  });
105
- onBeforeUnmount(() => {
106
- state.beforeUnmount();
107
- });
116
+ onBeforeUnmount(() => state.beforeUnmount());
108
117
  onUnmounted(() => {
109
118
  if (safeUnmount(getMotionElement(instance.$el)))
110
119
  state.unmount();
111
120
  });
112
- onBeforeUpdate(() => {
113
- state.beforeUpdate();
114
- });
121
+ onBeforeUpdate(() => state.beforeUpdate());
115
122
  onUpdated(() => {
116
123
  state.update({
117
124
  ...attrs,
118
125
  ...props,
126
+ transition: props.transition ?? config.value.transition,
127
+ motionConfig: config.value,
119
128
  initial: presenceInitial.value === false ? presenceInitial.value : props.initial === true ? void 0 : props.initial
120
129
  });
121
130
  });
@@ -133,28 +142,36 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
133
142
  if (isSVG) {
134
143
  const { attributes, style } = convertSvgStyleToAttributes(state.target);
135
144
  Object.assign(attrsProps, attributes);
136
- Object.assign(styleProps, style, props.style);
145
+ Object.assign(styleProps, style);
137
146
  }
138
147
  if (!state.isMounted()) {
139
- Object.assign(styleProps, state.target, props.style);
148
+ Object.assign(styleProps, state.target);
140
149
  }
141
- styleProps = createStyles(styleProps);
150
+ if (props.drag && props.dragListener !== false) {
151
+ Object.assign(styleProps, {
152
+ userSelect: "none",
153
+ WebkitUserSelect: "none",
154
+ WebkitTouchCallout: "none",
155
+ touchAction: props.drag === true ? "none" : `pan-${props.drag === "x" ? "y" : "x"}`
156
+ });
157
+ }
158
+ styleProps = createStyles({
159
+ ...styleProps,
160
+ ...props.style
161
+ });
142
162
  attrsProps.style = styleProps;
143
163
  return attrsProps;
144
164
  }
145
165
  return (_ctx, _cache) => {
146
- var _a, _b;
147
166
  return openBlock(), createBlock(unref(Primitive), mergeProps({
148
167
  as: _ctx.as,
149
168
  "as-child": _ctx.asChild
150
- }, getProps(), {
151
- "data-layout-group-key": (_b = (_a = unref(layoutGroup)) == null ? void 0 : _a.key) == null ? void 0 : _b.value
152
- }), {
169
+ }, getProps()), {
153
170
  default: withCtx(() => [
154
171
  renderSlot(_ctx.$slots, "default")
155
172
  ]),
156
173
  _: 3
157
- }, 16, ["as", "as-child", "data-layout-group-key"]);
174
+ }, 16, ["as", "as-child"]);
158
175
  };
159
176
  }
160
177
  });
@@ -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
  };
@@ -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,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
  };
@@ -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 = `
@@ -17,7 +17,8 @@ const utilities = {
17
17
  "useAnimate",
18
18
  "useInView",
19
19
  "useAnimationFrame",
20
- "useMotionValueEvent"
20
+ "useMotionValueEvent",
21
+ "useLayoutGroup"
21
22
  ]
22
23
  };
23
24
  export {
@@ -12,9 +12,8 @@ class LayoutFeature extends Feature {
12
12
  (_a = this.state.visualElement.projection) == null ? void 0 : _a.willUpdate();
13
13
  }
14
14
  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();
15
+ var _a;
16
+ (_a = this.state.visualElement.projection) == null ? void 0 : _a.root.didUpdate();
18
17
  }
19
18
  beforeMount() {
20
19
  }
@@ -32,16 +31,15 @@ class LayoutFeature extends Feature {
32
31
  }
33
32
  }
34
33
  beforeUnmount() {
35
- if (this.state.visualElement.projection) {
36
- this.state.visualElement.projection.willUpdate();
37
- }
38
34
  }
39
35
  unmount() {
40
- if (this.state.visualElement.projection) {
41
- this.state.visualElement.projection.unmount();
36
+ const projection = this.state.visualElement.projection;
37
+ if (projection) {
38
+ projection.root.didUpdate();
39
+ projection.finishAnimation();
42
40
  const layoutGroup = this.state.options.layoutGroup;
43
41
  if (layoutGroup == null ? void 0 : layoutGroup.group)
44
- layoutGroup.group.remove(this.state.visualElement.projection);
42
+ layoutGroup.group.remove(projection);
45
43
  }
46
44
  }
47
45
  }
@@ -23,12 +23,28 @@ class ProjectionFeature extends Feature {
23
23
  animationType: typeof options.layout === "string" ? options.layout : "both",
24
24
  // initialPromotionConfig
25
25
  layoutRoot: options.layoutRoot,
26
- layoutScroll: options.layoutScroll
26
+ layoutScroll: options.layoutScroll,
27
+ crossfade: options.crossfade
27
28
  });
28
29
  }
29
30
  beforeMount() {
30
31
  this.initProjection();
31
32
  }
33
+ update() {
34
+ const options = this.state.options;
35
+ this.state.visualElement.projection.setOptions({
36
+ layout: options.layout,
37
+ layoutId: options.layoutId,
38
+ // TODO: drag
39
+ alwaysMeasureLayout: false,
40
+ visualElement: this.state.visualElement,
41
+ animationType: typeof options.layout === "string" ? options.layout : "both",
42
+ // initialPromotionConfig
43
+ layoutRoot: options.layoutRoot,
44
+ layoutScroll: options.layoutScroll,
45
+ crossfade: options.crossfade
46
+ });
47
+ }
32
48
  mount() {
33
49
  var _a;
34
50
  (_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
2
  import { default as default3 } from "./components/AnimatePresence.vue.mjs";
3
3
  import { default as default4 } from "./components/LayoutGroup.vue.mjs";
4
- import { injectLayoutGroup, injectMotion, provideLayoutGroup, provideMotion, shouldInheritGroup, shouldInheritId } from "./components/context.mjs";
4
+ import { useLayoutGroup } from "./components/use-layout-group.mjs";
5
+ import { injectLayoutGroup, injectMotion, provideLayoutGroup, provideMotion } from "./components/context.mjs";
5
6
  import { components, utilities } from "./constants/index.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";
@@ -56,6 +59,7 @@ export {
56
59
  default3 as AnimatePresence,
57
60
  default4 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,
@@ -19,7 +19,7 @@ function animateVariantsChildren(state, activeState) {
19
19
  for (const name in activeState) {
20
20
  childState.activeStates[name] = true;
21
21
  const { definition, transition } = activeState[name];
22
- const { staggerChildren = 0, staggerDirection = 1, delayChildren = 0 } = transition;
22
+ const { staggerChildren = 0, staggerDirection = 1, delayChildren = 0 } = transition || {};
23
23
  const maxStaggerDuration = (variantChildren.size - 1) * staggerChildren;
24
24
  const generateStaggerDuration = staggerDirection === 1 ? (i = 0) => i * staggerChildren : (i = 0) => maxStaggerDuration - i * staggerChildren;
25
25
  const variant = resolveVariant(
@@ -47,7 +47,8 @@ class MotionState {
47
47
  attrs: {}
48
48
  },
49
49
  latestValues: {}
50
- }
50
+ },
51
+ reducedMotionConfig: options.motionConfig.reduceMotion
51
52
  });
52
53
  const initialVariantSource = options.initial === false ? "animate" : "initial";
53
54
  this.featureManager = new FeatureManager(this);
@@ -77,7 +78,8 @@ class MotionState {
77
78
  ...this.options,
78
79
  whileHover: this.options.hover,
79
80
  whileTap: this.options.press,
80
- whileInView: this.options.inView
81
+ whileInView: this.options.inView,
82
+ reducedMotionConfig: this.options.motionConfig.reduceMotion
81
83
  }, {
82
84
  isPresent: !doneCallbacks.has(this.element)
83
85
  });
@@ -1,4 +1,4 @@
1
- import { watch, onBeforeUnmount } from "vue";
1
+ import { watch } from "vue";
2
2
  import { animateValue } from "../external/.pnpm/framer-motion@11.15.0/external/framer-motion/dist/es/animation/animators/MainThreadAnimation.mjs";
3
3
  import { motionValue } from "../external/.pnpm/framer-motion@11.15.0/external/framer-motion/dist/es/value/index.mjs";
4
4
  import { frame, frameData } from "../external/.pnpm/framer-motion@11.15.0/external/framer-motion/dist/es/frameloop/frame.mjs";
@@ -39,13 +39,12 @@ function useSpring(source, config = {}) {
39
39
  });
40
40
  };
41
41
  watch(() => JSON.stringify(config), () => {
42
- const cleanup = value.attach((v, set) => {
42
+ value.attach((v, set) => {
43
43
  latestValue = v;
44
44
  latestSetter = set;
45
45
  frame.update(startAnimation);
46
46
  return value.get();
47
47
  }, stopAnimation);
48
- onBeforeUnmount(() => cleanup());
49
48
  }, { immediate: true });
50
49
  if (isMotionValue(source)) {
51
50
  source.on("change", (v) => {
@@ -1,7 +1,10 @@
1
1
  import { LayoutGroupProps } from './use-layout-group';
2
2
  declare function __VLS_template(): {
3
3
  slots: {
4
- default?(_: {}): any;
4
+ default?(_: {
5
+ renderKey: number;
6
+ forceRender: VoidFunction;
7
+ }): any;
5
8
  };
6
9
  refs: {};
7
10
  attrs: Partial<{}>;
@@ -3,6 +3,7 @@ import { ElementType, Options, SVGAttributesWithMotionValues, SetMotionValueType
3
3
  export interface MotionProps<T extends ElementType = 'div', K = unknown> extends Options<K> {
4
4
  as?: T;
5
5
  asChild?: boolean;
6
+ whileDrag?: Options['whileDrag'];
6
7
  }
7
8
  declare const _default: <T extends ElementType = "div", K = unknown>(__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<{
8
9
  props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps & Readonly<import('vue').ExtractPropTypes<{}>>, never>, never> & (Omit<SetMotionValueType<IntrinsicElementAttributes, keyof SVGAttributesWithMotionValues>[T], "asChild" | keyof Options<any>> & MotionProps<T, K>)> & import('vue').PublicProps;
@@ -14,6 +14,3 @@ export interface LayoutGroupState {
14
14
  key?: Ref<number>;
15
15
  }
16
16
  export declare const injectLayoutGroup: <T extends LayoutGroupState = LayoutGroupState>(fallback?: T) => T extends null ? LayoutGroupState : LayoutGroupState, provideLayoutGroup: (contextValue: LayoutGroupState) => LayoutGroupState;
17
- export type InheritOption = boolean | 'id';
18
- export declare function shouldInheritGroup(inherit: InheritOption): inherit is true;
19
- export declare function shouldInheritId(inherit: InheritOption): boolean;
@@ -0,0 +1,39 @@
1
+ declare function __VLS_template(): {
2
+ slots: {
3
+ default?(_: {}): any;
4
+ };
5
+ refs: {};
6
+ attrs: Partial<{}>;
7
+ };
8
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
9
+ declare const __VLS_component: import('vue').DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<import('./types').MotionConfigState>, {
10
+ reduceMotion: "user" | "never" | "always";
11
+ }>, {}, unknown, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<import('./types').MotionConfigState>, {
12
+ reduceMotion: "user" | "never" | "always";
13
+ }>>>, {
14
+ reduceMotion: "user" | "never" | "always";
15
+ }, {}>;
16
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
17
+ export default _default;
18
+ type __VLS_WithDefaults<P, D> = {
19
+ [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
20
+ default: D[K];
21
+ }> : P[K];
22
+ };
23
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
24
+ type __VLS_TypePropsToOption<T> = {
25
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
26
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
27
+ } : {
28
+ type: import('vue').PropType<T[K]>;
29
+ required: true;
30
+ };
31
+ };
32
+ type __VLS_WithTemplateSlots<T, S> = T & {
33
+ new (): {
34
+ $slots: S;
35
+ };
36
+ };
37
+ type __VLS_PrettifyLocal<T> = {
38
+ [K in keyof T]: T[K];
39
+ } & {};
@@ -0,0 +1,11 @@
1
+ import { MotionConfigState } from './types';
2
+ import { ComputedRef } from 'vue';
3
+ /**
4
+ * Default motion configuration
5
+ */
6
+ export declare const defaultConfig: MotionConfigState;
7
+ /**
8
+ * Context for sharing motion configuration with child components
9
+ */
10
+ export declare const injectMotionConfig: <T extends ComputedRef<MotionConfigState> = ComputedRef<MotionConfigState>>(fallback?: T) => T extends null ? ComputedRef<MotionConfigState> : ComputedRef<MotionConfigState>, provideMotionConfig: (contextValue: ComputedRef<MotionConfigState>) => ComputedRef<MotionConfigState>;
11
+ export declare function useMotionConfig(): ComputedRef<MotionConfigState>;
@@ -0,0 +1,2 @@
1
+ export { default as MotionConfig } from './MotionConfig';
2
+ export { provideMotionConfig, useMotionConfig } from './context';
@@ -0,0 +1,14 @@
1
+ import { Options } from '../../types';
2
+ /**
3
+ * Motion configuration state shared through context
4
+ */
5
+ export interface MotionConfigState {
6
+ /** Default transition settings for animations */
7
+ transition?: Options['transition'];
8
+ /** Controls motion reduction based on user preference or explicit setting */
9
+ reduceMotion?: 'user' | 'never' | 'always';
10
+ /** Custom nonce for CSP compliance with inline styles */
11
+ nonce?: string;
12
+ }
13
+ /** Props interface matching the config state */
14
+ export type MotionConfigProps = MotionConfigState;
@@ -17,4 +17,7 @@ export interface LayoutGroupProps {
17
17
  * Hook to create and manage a layout group
18
18
  * Handles group inheritance, force updates, and context management
19
19
  */
20
- export declare function useLayoutGroup(props: LayoutGroupProps): LayoutGroupState;
20
+ export declare function useLayoutGroupProvider(props: LayoutGroupProps): LayoutGroupState;
21
+ export declare function useLayoutGroup(): {
22
+ forceRender: VoidFunction;
23
+ };
@@ -0,0 +1 @@
1
+ export declare function useSlotChangeIndex(): import('vue').ComputedRef<number>;
@@ -1,4 +1,5 @@
1
1
  import { DragControls } from './use-drag-controls';
2
+ import { Variant } from '../../../types';
2
3
  import { Axis, BoundingBox, DragElastic, InertiaOptions, PanInfo } from 'framer-motion';
3
4
  export interface ResolvedConstraints {
4
5
  x: Partial<Axis>;
@@ -22,7 +23,7 @@ export interface DragHandlers {
22
23
  *
23
24
  * @public
24
25
  */
25
- onDragStart?: (event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => void;
26
+ onDragStart?: (event: PointerEvent, info: PanInfo) => void;
26
27
  /**
27
28
  * Callback function that fires when dragging ends.
28
29
  *
@@ -37,7 +38,7 @@ export interface DragHandlers {
37
38
  *
38
39
  * @public
39
40
  */
40
- onDragEnd?: (event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => void;
41
+ onDragEnd?: (event: PointerEvent, info: PanInfo) => void;
41
42
  /**
42
43
  * Callback function that fires when the component is dragged.
43
44
  *
@@ -52,7 +53,7 @@ export interface DragHandlers {
52
53
  *
53
54
  * @public
54
55
  */
55
- onDrag?: (event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => void;
56
+ onDrag?: (event: PointerEvent, info: PanInfo) => void;
56
57
  /**
57
58
  * Callback function that fires a drag direction is determined.
58
59
  *
@@ -220,4 +221,5 @@ export interface DragProps extends DragHandlers {
220
221
  * ```
221
222
  */
222
223
  dragControls?: DragControls;
224
+ whileDrag?: string | Variant;
223
225
  }
@@ -22,8 +22,3 @@ export interface DragOptions {
22
22
  timeConstant?: number;
23
23
  };
24
24
  }
25
- export interface DragHandlers {
26
- onDragStart?: (event: PointerEvent) => void;
27
- onDrag?: (event: PointerEvent) => void;
28
- onDragEnd?: (event: PointerEvent) => void;
29
- }
@@ -3,5 +3,6 @@ export declare class ProjectionFeature extends Feature {
3
3
  constructor(state: any);
4
4
  initProjection(): void;
5
5
  beforeMount(): void;
6
+ update(): void;
6
7
  mount(): void;
7
8
  }
@@ -4,4 +4,5 @@ export interface LayoutOptions {
4
4
  'layoutScroll'?: boolean;
5
5
  'layoutRoot'?: boolean;
6
6
  'data-framer-portal-id'?: string;
7
+ 'crossfade'?: boolean;
7
8
  }
@@ -4,7 +4,9 @@ export { default as Motion, type MotionProps } from './components/Motion';
4
4
  export { default as AnimatePresence } from './components/AnimatePresence';
5
5
  export type { AnimatePresenceProps } from './components/type';
6
6
  export { default as LayoutGroup } from './components/LayoutGroup';
7
+ export { useLayoutGroup } from './components/use-layout-group';
7
8
  export type { LayoutGroupProps } from './components/use-layout-group';
9
+ export * from './components/motion-config';
8
10
  export * from './components/context';
9
11
  export * from './value';
10
12
  export * from './constants';
@@ -9,6 +9,7 @@ import { HoverProps } from '../features/gestures/hover/types';
9
9
  import { InViewProps } from '../features/gestures/in-view/types';
10
10
  import { LayoutGroupState } from '../components/context';
11
11
  import { PanProps } from '../features/gestures/pan/types';
12
+ import { MotionConfigState } from '../components/motion-config/types';
12
13
  type AnimationPlaybackControls = ReturnType<typeof animate>;
13
14
  export interface Orchestration {
14
15
  delay?: number;
@@ -51,6 +52,7 @@ export interface Options<T = any> extends LayoutOptions, PressProps, HoverProps,
51
52
  transformTemplate?: (transform: TransformProperties, generatedTransform: string) => string;
52
53
  transition?: AnimateOptions;
53
54
  layoutGroup?: LayoutGroupState;
55
+ motionConfig?: MotionConfigState;
54
56
  }
55
57
  export interface MotionStateContext {
56
58
  initial?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "motion-v",
3
- "version": "0.5.0",
3
+ "version": "0.5.2-beta.1",
4
4
  "description": "",
5
5
  "author": "",
6
6
  "license": "MIT",