framer-motion 12.20.4 → 12.22.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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var create = require('./create-7q3QlJ1Z.js');
5
+ var create = require('./create-Dr1Bf9gl.js');
6
6
  require('motion-dom');
7
7
  require('motion-utils');
8
8
  require('react/jsx-runtime');
@@ -911,7 +911,6 @@ const metrics = {
911
911
  calculatedProjections: 0,
912
912
  };
913
913
  const transformAxes = ["", "X", "Y", "Z"];
914
- const hiddenVisibility = { visibility: "hidden" };
915
914
  /**
916
915
  * We use 1000 as the animation target as 0-1000 maps better to pixels than 0-1
917
916
  * which has a noticeable difference in spring animations
@@ -1133,8 +1132,17 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
1133
1132
  }
1134
1133
  if (attachResizeListener) {
1135
1134
  let cancelDelay;
1135
+ let innerWidth = 0;
1136
1136
  const resizeUnblockUpdate = () => (this.root.updateBlockedByResize = false);
1137
+ // Set initial innerWidth in a frame.read callback to batch the read
1138
+ motionDom.frame.read(() => {
1139
+ innerWidth = window.innerWidth;
1140
+ });
1137
1141
  attachResizeListener(instance, () => {
1142
+ const newInnerWidth = window.innerWidth;
1143
+ if (newInnerWidth === innerWidth)
1144
+ return;
1145
+ innerWidth = newInnerWidth;
1138
1146
  this.root.updateBlockedByResize = true;
1139
1147
  cancelDelay && cancelDelay();
1140
1148
  cancelDelay = delay(resizeUnblockUpdate, 250);
@@ -2141,59 +2149,60 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
2141
2149
  // see the element with the reset rotate value applied.
2142
2150
  visualElement.scheduleRender();
2143
2151
  }
2144
- getProjectionStyles(styleProp) {
2152
+ applyProjectionStyles(targetStyle, // CSSStyleDeclaration - doesn't allow numbers to be assigned to properties
2153
+ styleProp) {
2145
2154
  if (!this.instance || this.isSVG)
2146
- return undefined;
2155
+ return;
2147
2156
  if (!this.isVisible) {
2148
- return hiddenVisibility;
2157
+ targetStyle.visibility = "hidden";
2158
+ return;
2149
2159
  }
2150
- const styles = {
2151
- visibility: "",
2152
- };
2153
2160
  const transformTemplate = this.getTransformTemplate();
2154
2161
  if (this.needsReset) {
2155
2162
  this.needsReset = false;
2156
- styles.opacity = "";
2157
- styles.pointerEvents =
2163
+ targetStyle.visibility = "";
2164
+ targetStyle.opacity = "";
2165
+ targetStyle.pointerEvents =
2158
2166
  resolveMotionValue(styleProp?.pointerEvents) || "";
2159
- styles.transform = transformTemplate
2167
+ targetStyle.transform = transformTemplate
2160
2168
  ? transformTemplate(this.latestValues, "")
2161
2169
  : "none";
2162
- return styles;
2170
+ return;
2163
2171
  }
2164
2172
  const lead = this.getLead();
2165
2173
  if (!this.projectionDelta || !this.layout || !lead.target) {
2166
- const emptyStyles = {};
2167
2174
  if (this.options.layoutId) {
2168
- emptyStyles.opacity =
2175
+ targetStyle.opacity =
2169
2176
  this.latestValues.opacity !== undefined
2170
2177
  ? this.latestValues.opacity
2171
2178
  : 1;
2172
- emptyStyles.pointerEvents =
2179
+ targetStyle.pointerEvents =
2173
2180
  resolveMotionValue(styleProp?.pointerEvents) || "";
2174
2181
  }
2175
2182
  if (this.hasProjected && !hasTransform(this.latestValues)) {
2176
- emptyStyles.transform = transformTemplate
2183
+ targetStyle.transform = transformTemplate
2177
2184
  ? transformTemplate({}, "")
2178
2185
  : "none";
2179
2186
  this.hasProjected = false;
2180
2187
  }
2181
- return emptyStyles;
2188
+ return;
2182
2189
  }
2190
+ targetStyle.visibility = "";
2183
2191
  const valuesToRender = lead.animationValues || lead.latestValues;
2184
2192
  this.applyTransformsToTarget();
2185
- styles.transform = buildProjectionTransform(this.projectionDeltaWithTransform, this.treeScale, valuesToRender);
2193
+ let transform = buildProjectionTransform(this.projectionDeltaWithTransform, this.treeScale, valuesToRender);
2186
2194
  if (transformTemplate) {
2187
- styles.transform = transformTemplate(valuesToRender, styles.transform);
2195
+ transform = transformTemplate(valuesToRender, transform);
2188
2196
  }
2197
+ targetStyle.transform = transform;
2189
2198
  const { x, y } = this.projectionDelta;
2190
- styles.transformOrigin = `${x.origin * 100}% ${y.origin * 100}% 0`;
2199
+ targetStyle.transformOrigin = `${x.origin * 100}% ${y.origin * 100}% 0`;
2191
2200
  if (lead.animationValues) {
2192
2201
  /**
2193
2202
  * If the lead component is animating, assign this either the entering/leaving
2194
2203
  * opacity
2195
2204
  */
2196
- styles.opacity =
2205
+ targetStyle.opacity =
2197
2206
  lead === this
2198
2207
  ? valuesToRender.opacity ??
2199
2208
  this.latestValues.opacity ??
@@ -2207,7 +2216,7 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
2207
2216
  * Or we're not animating at all, set the lead component to its layout
2208
2217
  * opacity and other components to hidden.
2209
2218
  */
2210
- styles.opacity =
2219
+ targetStyle.opacity =
2211
2220
  lead === this
2212
2221
  ? valuesToRender.opacity !== undefined
2213
2222
  ? valuesToRender.opacity
@@ -2229,13 +2238,13 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
2229
2238
  * vulnerable to distortion if the element changes size without
2230
2239
  * a corresponding layout animation.
2231
2240
  */
2232
- const corrected = styles.transform === "none"
2241
+ const corrected = transform === "none"
2233
2242
  ? valuesToRender[key]
2234
2243
  : correct(valuesToRender[key], lead);
2235
2244
  if (applyTo) {
2236
2245
  const num = applyTo.length;
2237
2246
  for (let i = 0; i < num; i++) {
2238
- styles[applyTo[i]] = corrected;
2247
+ targetStyle[applyTo[i]] = corrected;
2239
2248
  }
2240
2249
  }
2241
2250
  else {
@@ -2246,7 +2255,7 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
2246
2255
  this.options.visualElement.renderState.vars[key] = corrected;
2247
2256
  }
2248
2257
  else {
2249
- styles[key] = corrected;
2258
+ targetStyle[key] = corrected;
2250
2259
  }
2251
2260
  }
2252
2261
  }
@@ -2256,12 +2265,11 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
2256
2265
  * pointer events on the lead.
2257
2266
  */
2258
2267
  if (this.options.layoutId) {
2259
- styles.pointerEvents =
2268
+ targetStyle.pointerEvents =
2260
2269
  lead === this
2261
2270
  ? resolveMotionValue(styleProp?.pointerEvents) || ""
2262
2271
  : "none";
2263
2272
  }
2264
- return styles;
2265
2273
  }
2266
2274
  clearSnapshot() {
2267
2275
  this.resumeFrom = this.snapshot = undefined;
@@ -3415,10 +3423,8 @@ function renderHTML(element, { style, vars }, styleProp, projection) {
3415
3423
  // CSSStyleDeclaration has [index: number]: string; in the types, so we use that as key type.
3416
3424
  elementStyle[key] = style[key];
3417
3425
  }
3418
- const projectionStyle = projection?.getProjectionStyles(styleProp);
3419
- for (key in projectionStyle) {
3420
- elementStyle[key] = projectionStyle[key];
3421
- }
3426
+ // Write projection styles directly to element style
3427
+ projection?.applyProjectionStyles(elementStyle, styleProp);
3422
3428
  for (key in vars) {
3423
3429
  // Loop over any CSS variables and assign those.
3424
3430
  // They can only be assigned using `setProperty`.
@@ -3758,7 +3764,7 @@ function animateVariant(visualElement, variant, options = {}) {
3758
3764
  const getChildAnimations = visualElement.variantChildren && visualElement.variantChildren.size
3759
3765
  ? (forwardDelay = 0) => {
3760
3766
  const { delayChildren = 0, staggerChildren, staggerDirection, } = transition;
3761
- return animateChildren(visualElement, variant, delayChildren + forwardDelay, staggerChildren, staggerDirection, options);
3767
+ return animateChildren(visualElement, variant, forwardDelay, delayChildren, staggerChildren, staggerDirection, options);
3762
3768
  }
3763
3769
  : () => Promise.resolve();
3764
3770
  /**
@@ -3776,19 +3782,26 @@ function animateVariant(visualElement, variant, options = {}) {
3776
3782
  return Promise.all([getAnimation(), getChildAnimations(options.delay)]);
3777
3783
  }
3778
3784
  }
3779
- function animateChildren(visualElement, variant, delayChildren = 0, staggerChildren = 0, staggerDirection = 1, options) {
3785
+ function animateChildren(visualElement, variant, delay = 0, delayChildren = 0, staggerChildren = 0, staggerDirection = 1, options) {
3780
3786
  const animations = [];
3781
- const maxStaggerDuration = (visualElement.variantChildren.size - 1) * staggerChildren;
3782
- const generateStaggerDuration = staggerDirection === 1
3783
- ? (i = 0) => i * staggerChildren
3784
- : (i = 0) => maxStaggerDuration - i * staggerChildren;
3787
+ const numChildren = visualElement.variantChildren.size;
3788
+ const maxStaggerDuration = (numChildren - 1) * staggerChildren;
3789
+ const delayIsFunction = typeof delayChildren === "function";
3790
+ const generateStaggerDuration = delayIsFunction
3791
+ ? (i) => delayChildren(i, numChildren)
3792
+ : // Support deprecated staggerChildren
3793
+ staggerDirection === 1
3794
+ ? (i = 0) => i * staggerChildren
3795
+ : (i = 0) => maxStaggerDuration - i * staggerChildren;
3785
3796
  Array.from(visualElement.variantChildren)
3786
3797
  .sort(sortByTreeOrder)
3787
3798
  .forEach((child, i) => {
3788
3799
  child.notify("AnimationStart", variant);
3789
3800
  animations.push(animateVariant(child, variant, {
3790
3801
  ...options,
3791
- delay: delayChildren + generateStaggerDuration(i),
3802
+ delay: delay +
3803
+ (delayIsFunction ? 0 : delayChildren) +
3804
+ generateStaggerDuration(i),
3792
3805
  }).then(() => child.notify("AnimationComplete", variant)));
3793
3806
  });
3794
3807
  return Promise.all(animations);
@@ -4311,7 +4324,7 @@ function distance2D(a, b) {
4311
4324
  * @internal
4312
4325
  */
4313
4326
  class PanSession {
4314
- constructor(event, handlers, { transformPagePoint, contextWindow, dragSnapToOrigin = false, } = {}) {
4327
+ constructor(event, handlers, { transformPagePoint, contextWindow = window, dragSnapToOrigin = false, distanceThreshold = 3, } = {}) {
4315
4328
  /**
4316
4329
  * @internal
4317
4330
  */
@@ -4339,8 +4352,8 @@ class PanSession {
4339
4352
  const isPanStarted = this.startEvent !== null;
4340
4353
  // Only start panning if the offset is larger than 3 pixels. If we make it
4341
4354
  // any larger than this we'll want to reset the pointer history
4342
- // on the first update to avoid visual snapping to the cursoe.
4343
- const isDistancePastThreshold = distance2D(info.offset, { x: 0, y: 0 }) >= 3;
4355
+ // on the first update to avoid visual snapping to the cursor.
4356
+ const isDistancePastThreshold = distance2D(info.offset, { x: 0, y: 0 }) >= this.distanceThreshold;
4344
4357
  if (!isPanStarted && !isDistancePastThreshold)
4345
4358
  return;
4346
4359
  const { point } = info;
@@ -4380,6 +4393,7 @@ class PanSession {
4380
4393
  this.dragSnapToOrigin = dragSnapToOrigin;
4381
4394
  this.handlers = handlers;
4382
4395
  this.transformPagePoint = transformPagePoint;
4396
+ this.distanceThreshold = distanceThreshold;
4383
4397
  this.contextWindow = contextWindow || window;
4384
4398
  const info = extractEventInfo(event);
4385
4399
  const initialInfo = transformPoint(info, this.transformPagePoint);
@@ -4578,10 +4592,6 @@ function resolvePointElastic(dragElastic, label) {
4578
4592
  }
4579
4593
 
4580
4594
  const elementDragControls = new WeakMap();
4581
- /**
4582
- *
4583
- */
4584
- // let latestPointerEvent: PointerEvent
4585
4595
  class VisualElementDragControls {
4586
4596
  constructor(visualElement) {
4587
4597
  this.openDragLock = null;
@@ -4599,7 +4609,7 @@ class VisualElementDragControls {
4599
4609
  this.elastic = createBox();
4600
4610
  this.visualElement = visualElement;
4601
4611
  }
4602
- start(originEvent, { snapToCursor = false } = {}) {
4612
+ start(originEvent, { snapToCursor = false, distanceThreshold } = {}) {
4603
4613
  /**
4604
4614
  * Don't start dragging if this component is exiting
4605
4615
  */
@@ -4706,6 +4716,7 @@ class VisualElementDragControls {
4706
4716
  }, {
4707
4717
  transformPagePoint: this.visualElement.getTransformPagePoint(),
4708
4718
  dragSnapToOrigin,
4719
+ distanceThreshold,
4709
4720
  contextWindow: getContextWindow(this.visualElement),
4710
4721
  });
4711
4722
  }
package/dist/cjs/dom.js CHANGED
@@ -1449,10 +1449,8 @@ function renderHTML(element, { style, vars }, styleProp, projection) {
1449
1449
  // CSSStyleDeclaration has [index: number]: string; in the types, so we use that as key type.
1450
1450
  elementStyle[key] = style[key];
1451
1451
  }
1452
- const projectionStyle = projection?.getProjectionStyles(styleProp);
1453
- for (key in projectionStyle) {
1454
- elementStyle[key] = projectionStyle[key];
1455
- }
1452
+ // Write projection styles directly to element style
1453
+ projection?.applyProjectionStyles(elementStyle, styleProp);
1456
1454
  for (key in vars) {
1457
1455
  // Loop over any CSS variables and assign those.
1458
1456
  // They can only be assigned using `setProperty`.
@@ -2423,29 +2421,6 @@ function inView(elementOrSelector, onStart, { root, margin: rootMargin, amount =
2423
2421
  return () => observer.disconnect();
2424
2422
  }
2425
2423
 
2426
- function getOriginIndex(from, total) {
2427
- if (from === "first") {
2428
- return 0;
2429
- }
2430
- else {
2431
- const lastIndex = total - 1;
2432
- return from === "last" ? lastIndex : lastIndex / 2;
2433
- }
2434
- }
2435
- function stagger(duration = 0.1, { startDelay = 0, from = 0, ease } = {}) {
2436
- return (i, total) => {
2437
- const fromIndex = typeof from === "number" ? from : getOriginIndex(from, total);
2438
- const distance = Math.abs(fromIndex - i);
2439
- let delay = duration * distance;
2440
- if (ease) {
2441
- const maxDelay = total * duration;
2442
- const easingFunction = motionUtils.easingDefinitionToFunction(ease);
2443
- delay = easingFunction(delay / maxDelay) * maxDelay;
2444
- }
2445
- return startDelay + delay;
2446
- };
2447
- }
2448
-
2449
2424
  /**
2450
2425
  * Timeout defined in ms
2451
2426
  */
@@ -2482,7 +2457,6 @@ exports.distance2D = distance2D;
2482
2457
  exports.inView = inView;
2483
2458
  exports.scroll = scroll;
2484
2459
  exports.scrollInfo = scrollInfo;
2485
- exports.stagger = stagger;
2486
2460
  Object.keys(motionDom).forEach(function (k) {
2487
2461
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
2488
2462
  enumerable: true,
package/dist/cjs/index.js CHANGED
@@ -4,7 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var React = require('react');
7
- var create = require('./create-7q3QlJ1Z.js');
7
+ var create = require('./create-Dr1Bf9gl.js');
8
8
  var motionDom = require('motion-dom');
9
9
  var motionUtils = require('motion-utils');
10
10
 
@@ -1807,29 +1807,6 @@ function inView(elementOrSelector, onStart, { root, margin: rootMargin, amount =
1807
1807
  return () => observer.disconnect();
1808
1808
  }
1809
1809
 
1810
- function getOriginIndex(from, total) {
1811
- if (from === "first") {
1812
- return 0;
1813
- }
1814
- else {
1815
- const lastIndex = total - 1;
1816
- return from === "last" ? lastIndex : lastIndex / 2;
1817
- }
1818
- }
1819
- function stagger(duration = 0.1, { startDelay = 0, from = 0, ease } = {}) {
1820
- return (i, total) => {
1821
- const fromIndex = typeof from === "number" ? from : getOriginIndex(from, total);
1822
- const distance = Math.abs(fromIndex - i);
1823
- let delay = duration * distance;
1824
- if (ease) {
1825
- const maxDelay = total * duration;
1826
- const easingFunction = motionUtils.easingDefinitionToFunction(ease);
1827
- delay = easingFunction(delay / maxDelay) * maxDelay;
1828
- }
1829
- return startDelay + delay;
1830
- };
1831
- }
1832
-
1833
1810
  const createMinimalMotionComponent =
1834
1811
  /*@__PURE__*/ create.createMotionComponentFactory();
1835
1812
 
@@ -2887,7 +2864,6 @@ exports.m = m;
2887
2864
  exports.motion = motion;
2888
2865
  exports.scroll = scroll;
2889
2866
  exports.scrollInfo = scrollInfo;
2890
- exports.stagger = stagger;
2891
2867
  exports.startOptimizedAppearAnimation = startOptimizedAppearAnimation;
2892
2868
  exports.unwrapMotionComponent = unwrapMotionComponent;
2893
2869
  exports.useAnimate = useAnimate;
package/dist/dom.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { UnresolvedValueKeyframe, MotionValue, Transition, ElementOrSelector, DOMKeyframesDefinition, AnimationOptions, AnimationPlaybackOptions, AnyResolvedKeyframe, AnimationScope, AnimationPlaybackControlsWithThen, ValueAnimationTransition, AnimationPlaybackControls, DynamicOption } from 'motion-dom';
1
+ import { UnresolvedValueKeyframe, MotionValue, Transition, ElementOrSelector, DOMKeyframesDefinition, AnimationOptions, AnimationPlaybackOptions, AnyResolvedKeyframe, AnimationScope, AnimationPlaybackControlsWithThen, ValueAnimationTransition, AnimationPlaybackControls } from 'motion-dom';
2
2
  export * from 'motion-dom';
3
3
  import { Easing, EasingFunction, Point } from 'motion-utils';
4
4
  export * from 'motion-utils';
@@ -142,18 +142,10 @@ interface InViewOptions {
142
142
  }
143
143
  declare function inView(elementOrSelector: ElementOrSelector, onStart: (element: Element, entry: IntersectionObserverEntry) => void | ViewChangeHandler, { root, margin: rootMargin, amount }?: InViewOptions): VoidFunction;
144
144
 
145
- type StaggerOrigin = "first" | "last" | "center" | number;
146
- type StaggerOptions = {
147
- startDelay?: number;
148
- from?: StaggerOrigin;
149
- ease?: Easing;
150
- };
151
- declare function stagger(duration?: number, { startDelay, from, ease }?: StaggerOptions): DynamicOption<number>;
152
-
153
145
  type DelayedFunction = (overshoot: number) => void;
154
146
  declare function delayInSeconds(callback: DelayedFunction, timeout: number): () => void;
155
147
 
156
148
  declare const distance: (a: number, b: number) => number;
157
149
  declare function distance2D(a: Point, b: Point): number;
158
150
 
159
- export { type AbsoluteKeyframe, type AnimationSequence, type At, type DOMSegment, type DOMSegmentWithTransition, type DelayedFunction, type MotionValueSegment, type MotionValueSegmentWithTransition, type ObjectSegment, type ObjectSegmentWithTransition, type ObjectTarget, type ResolvedAnimationDefinition, type ResolvedAnimationDefinitions, type Segment, type SequenceLabel, type SequenceLabelWithTime, type SequenceMap, type SequenceOptions, type SequenceTime, type ValueSequence, animate, animateMini, createScopedAnimate, delayInSeconds as delay, distance, distance2D, inView, scroll, scrollInfo, stagger };
151
+ export { type AbsoluteKeyframe, type AnimationSequence, type At, type DOMSegment, type DOMSegmentWithTransition, type DelayedFunction, type MotionValueSegment, type MotionValueSegmentWithTransition, type ObjectSegment, type ObjectSegmentWithTransition, type ObjectTarget, type ResolvedAnimationDefinition, type ResolvedAnimationDefinitions, type Segment, type SequenceLabel, type SequenceLabelWithTime, type SequenceMap, type SequenceOptions, type SequenceTime, type ValueSequence, animate, animateMini, createScopedAnimate, delayInSeconds as delay, distance, distance2D, inView, scroll, scrollInfo };