framer-motion 6.3.14 → 6.4.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
@@ -8,6 +8,7 @@ var heyListen = require('hey-listen');
8
8
  var sync = require('framesync');
9
9
  var popmotion = require('popmotion');
10
10
  var styleValueTypes = require('style-value-types');
11
+ var dom = require('@motionone/dom');
11
12
 
12
13
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
13
14
 
@@ -472,7 +473,7 @@ var MotionValue = /** @class */ (function () {
472
473
  * This will be replaced by the build step with the latest version number.
473
474
  * When MotionValues are provided to motion components, warn if versions are mixed.
474
475
  */
475
- this.version = "6.3.14";
476
+ this.version = "6.4.0";
476
477
  /**
477
478
  * Duration, in milliseconds, since last updating frame.
478
479
  *
@@ -1830,7 +1831,7 @@ var globalProjectionState = {
1830
1831
  hasEverUpdated: false,
1831
1832
  };
1832
1833
  function createProjectionNode(_a) {
1833
- var attachResizeListener = _a.attachResizeListener, defaultParent = _a.defaultParent, measureScroll = _a.measureScroll, resetTransform = _a.resetTransform;
1834
+ var attachResizeListener = _a.attachResizeListener, defaultParent = _a.defaultParent, measureScroll = _a.measureScroll, checkIsScrollRoot = _a.checkIsScrollRoot, resetTransform = _a.resetTransform;
1834
1835
  return /** @class */ (function () {
1835
1836
  function ProjectionNode(id, latestValues, parent) {
1836
1837
  var _this = this;
@@ -2233,6 +2234,7 @@ function createProjectionNode(_a) {
2233
2234
  };
2234
2235
  ProjectionNode.prototype.updateScroll = function () {
2235
2236
  if (this.options.layoutScroll && this.instance) {
2237
+ this.isScrollRoot = checkIsScrollRoot(this.instance);
2236
2238
  this.scroll = measureScroll(this.instance);
2237
2239
  }
2238
2240
  };
@@ -2276,8 +2278,24 @@ function createProjectionNode(_a) {
2276
2278
  */
2277
2279
  for (var i = 0; i < this.path.length; i++) {
2278
2280
  var node = this.path[i];
2279
- var scroll_1 = node.scroll, options = node.options;
2281
+ var scroll_1 = node.scroll, options = node.options, isScrollRoot = node.isScrollRoot;
2280
2282
  if (node !== this.root && scroll_1 && options.layoutScroll) {
2283
+ /**
2284
+ * If this is a new scroll root, we want to remove all previous scrolls
2285
+ * from the viewport box.
2286
+ */
2287
+ if (isScrollRoot) {
2288
+ copyBoxInto(boxWithoutScroll, box);
2289
+ var rootScroll = this.root.scroll;
2290
+ /**
2291
+ * Undo the application of page scroll that was originally added
2292
+ * to the measured bounding box.
2293
+ */
2294
+ if (rootScroll) {
2295
+ translateAxis(boxWithoutScroll.x, -rootScroll.x);
2296
+ translateAxis(boxWithoutScroll.y, -rootScroll.y);
2297
+ }
2298
+ }
2281
2299
  translateAxis(boxWithoutScroll.x, scroll_1.x);
2282
2300
  translateAxis(boxWithoutScroll.y, scroll_1.y);
2283
2301
  }
@@ -5966,7 +5984,7 @@ function updateMotionValuesFromProps(element, next, prev) {
5966
5984
  * and warn against mismatches.
5967
5985
  */
5968
5986
  if (process.env.NODE_ENV === "development") {
5969
- warnOnce(nextValue.version === "6.3.14", "Attempting to mix Framer Motion versions ".concat(nextValue.version, " with 6.3.14 may not work as expected."));
5987
+ warnOnce(nextValue.version === "6.4.0", "Attempting to mix Framer Motion versions ".concat(nextValue.version, " with 6.4.0 may not work as expected."));
5970
5988
  }
5971
5989
  }
5972
5990
  else if (isMotionValue(prevValue)) {
@@ -7080,6 +7098,7 @@ var DocumentProjectionNode = createProjectionNode({
7080
7098
  x: document.documentElement.scrollLeft || document.body.scrollLeft,
7081
7099
  y: document.documentElement.scrollTop || document.body.scrollTop,
7082
7100
  }); },
7101
+ checkIsScrollRoot: function () { return true; },
7083
7102
  });
7084
7103
 
7085
7104
  var rootProjectionNode = {
@@ -7102,6 +7121,9 @@ var HTMLProjectionNode = createProjectionNode({
7102
7121
  resetTransform: function (instance, value) {
7103
7122
  instance.style.transform = value !== null && value !== void 0 ? value : "none";
7104
7123
  },
7124
+ checkIsScrollRoot: function (instance) {
7125
+ return Boolean(window.getComputedStyle(instance).position === "fixed");
7126
+ },
7105
7127
  });
7106
7128
 
7107
7129
  var featureBundle = tslib.__assign(tslib.__assign(tslib.__assign(tslib.__assign({}, animations), gestureAnimations), drag), layoutFeatures);
@@ -8164,6 +8186,27 @@ function useCycle() {
8164
8186
  return [item, runCycle];
8165
8187
  }
8166
8188
 
8189
+ function useInView(ref, _a) {
8190
+ var _b = _a === void 0 ? {} : _a, root = _b.root, margin = _b.margin, amount = _b.amount, _c = _b.once, once = _c === void 0 ? false : _c;
8191
+ var _d = tslib.__read(React.useState(false), 2), isInView = _d[0], setInView = _d[1];
8192
+ React.useEffect(function () {
8193
+ var _a;
8194
+ if (!ref.current || (once && isInView))
8195
+ return;
8196
+ var onEnter = function () {
8197
+ setInView(true);
8198
+ return once ? undefined : function () { return setInView(false); };
8199
+ };
8200
+ var options = {
8201
+ root: (_a = root === null || root === void 0 ? void 0 : root.current) !== null && _a !== void 0 ? _a : undefined,
8202
+ margin: margin,
8203
+ amount: amount === "some" ? "any" : amount,
8204
+ };
8205
+ return dom.inView(ref.current, onEnter, options);
8206
+ }, [root, ref, margin, once]);
8207
+ return isInView;
8208
+ }
8209
+
8167
8210
  /**
8168
8211
  * Can manually trigger a drag gesture on one or more `drag`-enabled `motion` components.
8169
8212
  *
@@ -8437,6 +8480,7 @@ exports.useDomEvent = useDomEvent;
8437
8480
  exports.useDragControls = useDragControls;
8438
8481
  exports.useElementScroll = useElementScroll;
8439
8482
  exports.useForceUpdate = useForceUpdate;
8483
+ exports.useInView = useInView;
8440
8484
  exports.useInstantLayoutTransition = useInstantLayoutTransition;
8441
8485
  exports.useInstantTransition = useInstantTransition;
8442
8486
  exports.useIsPresent = useIsPresent;
package/dist/es/index.mjs CHANGED
@@ -28,6 +28,7 @@ export { useCycle } from './utils/use-cycle.mjs';
28
28
  export { transform } from './utils/transform.mjs';
29
29
  export { isValidMotionProp } from './motion/utils/valid-prop.mjs';
30
30
  export { useIsPresent, usePresence } from './components/AnimatePresence/use-presence.mjs';
31
+ export { useInView } from './utils/use-in-view.mjs';
31
32
  export { DragControls, useDragControls } from './gestures/drag/use-drag-controls.mjs';
32
33
  export { useDomEvent } from './events/use-dom-event.mjs';
33
34
  export { createMotionComponent } from './motion/index.mjs';
@@ -7,6 +7,7 @@ var DocumentProjectionNode = createProjectionNode({
7
7
  x: document.documentElement.scrollLeft || document.body.scrollLeft,
8
8
  y: document.documentElement.scrollTop || document.body.scrollTop,
9
9
  }); },
10
+ checkIsScrollRoot: function () { return true; },
10
11
  });
11
12
 
12
13
  export { DocumentProjectionNode };
@@ -21,6 +21,9 @@ var HTMLProjectionNode = createProjectionNode({
21
21
  resetTransform: function (instance, value) {
22
22
  instance.style.transform = value !== null && value !== void 0 ? value : "none";
23
23
  },
24
+ checkIsScrollRoot: function (instance) {
25
+ return Boolean(window.getComputedStyle(instance).position === "fixed");
26
+ },
24
27
  });
25
28
 
26
29
  export { HTMLProjectionNode, rootProjectionNode };
@@ -43,7 +43,7 @@ var globalProjectionState = {
43
43
  hasEverUpdated: false,
44
44
  };
45
45
  function createProjectionNode(_a) {
46
- var attachResizeListener = _a.attachResizeListener, defaultParent = _a.defaultParent, measureScroll = _a.measureScroll, resetTransform = _a.resetTransform;
46
+ var attachResizeListener = _a.attachResizeListener, defaultParent = _a.defaultParent, measureScroll = _a.measureScroll, checkIsScrollRoot = _a.checkIsScrollRoot, resetTransform = _a.resetTransform;
47
47
  return /** @class */ (function () {
48
48
  function ProjectionNode(id, latestValues, parent) {
49
49
  var _this = this;
@@ -446,6 +446,7 @@ function createProjectionNode(_a) {
446
446
  };
447
447
  ProjectionNode.prototype.updateScroll = function () {
448
448
  if (this.options.layoutScroll && this.instance) {
449
+ this.isScrollRoot = checkIsScrollRoot(this.instance);
449
450
  this.scroll = measureScroll(this.instance);
450
451
  }
451
452
  };
@@ -489,8 +490,24 @@ function createProjectionNode(_a) {
489
490
  */
490
491
  for (var i = 0; i < this.path.length; i++) {
491
492
  var node = this.path[i];
492
- var scroll_1 = node.scroll, options = node.options;
493
+ var scroll_1 = node.scroll, options = node.options, isScrollRoot = node.isScrollRoot;
493
494
  if (node !== this.root && scroll_1 && options.layoutScroll) {
495
+ /**
496
+ * If this is a new scroll root, we want to remove all previous scrolls
497
+ * from the viewport box.
498
+ */
499
+ if (isScrollRoot) {
500
+ copyBoxInto(boxWithoutScroll, box);
501
+ var rootScroll = this.root.scroll;
502
+ /**
503
+ * Undo the application of page scroll that was originally added
504
+ * to the measured bounding box.
505
+ */
506
+ if (rootScroll) {
507
+ translateAxis(boxWithoutScroll.x, -rootScroll.x);
508
+ translateAxis(boxWithoutScroll.y, -rootScroll.y);
509
+ }
510
+ }
494
511
  translateAxis(boxWithoutScroll.x, scroll_1.x);
495
512
  translateAxis(boxWithoutScroll.y, scroll_1.y);
496
513
  }
@@ -18,7 +18,7 @@ function updateMotionValuesFromProps(element, next, prev) {
18
18
  * and warn against mismatches.
19
19
  */
20
20
  if (process.env.NODE_ENV === "development") {
21
- warnOnce(nextValue.version === "6.3.14", "Attempting to mix Framer Motion versions ".concat(nextValue.version, " with 6.3.14 may not work as expected."));
21
+ warnOnce(nextValue.version === "6.4.0", "Attempting to mix Framer Motion versions ".concat(nextValue.version, " with 6.4.0 may not work as expected."));
22
22
  }
23
23
  }
24
24
  else if (isMotionValue(prevValue)) {
@@ -0,0 +1,26 @@
1
+ import { __read } from 'tslib';
2
+ import { useState, useEffect } from 'react';
3
+ import { inView } from '@motionone/dom';
4
+
5
+ function useInView(ref, _a) {
6
+ var _b = _a === void 0 ? {} : _a, root = _b.root, margin = _b.margin, amount = _b.amount, _c = _b.once, once = _c === void 0 ? false : _c;
7
+ var _d = __read(useState(false), 2), isInView = _d[0], setInView = _d[1];
8
+ useEffect(function () {
9
+ var _a;
10
+ if (!ref.current || (once && isInView))
11
+ return;
12
+ var onEnter = function () {
13
+ setInView(true);
14
+ return once ? undefined : function () { return setInView(false); };
15
+ };
16
+ var options = {
17
+ root: (_a = root === null || root === void 0 ? void 0 : root.current) !== null && _a !== void 0 ? _a : undefined,
18
+ margin: margin,
19
+ amount: amount === "some" ? "any" : amount,
20
+ };
21
+ return inView(ref.current, onEnter, options);
22
+ }, [root, ref, margin, once]);
23
+ return isInView;
24
+ }
25
+
26
+ export { useInView };
@@ -25,7 +25,7 @@ var MotionValue = /** @class */ (function () {
25
25
  * This will be replaced by the build step with the latest version number.
26
26
  * When MotionValues are provided to motion components, warn if versions are mixed.
27
27
  */
28
- this.version = "6.3.14";
28
+ this.version = "6.4.0";
29
29
  /**
30
30
  * Duration, in milliseconds, since last updating frame.
31
31
  *
@@ -1706,7 +1706,7 @@
1706
1706
  * This will be replaced by the build step with the latest version number.
1707
1707
  * When MotionValues are provided to motion components, warn if versions are mixed.
1708
1708
  */
1709
- this.version = "6.3.14";
1709
+ this.version = "6.4.0";
1710
1710
  /**
1711
1711
  * Duration, in milliseconds, since last updating frame.
1712
1712
  *
@@ -3064,7 +3064,7 @@
3064
3064
  hasEverUpdated: false,
3065
3065
  };
3066
3066
  function createProjectionNode(_a) {
3067
- var attachResizeListener = _a.attachResizeListener, defaultParent = _a.defaultParent, measureScroll = _a.measureScroll, resetTransform = _a.resetTransform;
3067
+ var attachResizeListener = _a.attachResizeListener, defaultParent = _a.defaultParent, measureScroll = _a.measureScroll, checkIsScrollRoot = _a.checkIsScrollRoot, resetTransform = _a.resetTransform;
3068
3068
  return /** @class */ (function () {
3069
3069
  function ProjectionNode(id, latestValues, parent) {
3070
3070
  var _this = this;
@@ -3467,6 +3467,7 @@
3467
3467
  };
3468
3468
  ProjectionNode.prototype.updateScroll = function () {
3469
3469
  if (this.options.layoutScroll && this.instance) {
3470
+ this.isScrollRoot = checkIsScrollRoot(this.instance);
3470
3471
  this.scroll = measureScroll(this.instance);
3471
3472
  }
3472
3473
  };
@@ -3510,8 +3511,24 @@
3510
3511
  */
3511
3512
  for (var i = 0; i < this.path.length; i++) {
3512
3513
  var node = this.path[i];
3513
- var scroll_1 = node.scroll, options = node.options;
3514
+ var scroll_1 = node.scroll, options = node.options, isScrollRoot = node.isScrollRoot;
3514
3515
  if (node !== this.root && scroll_1 && options.layoutScroll) {
3516
+ /**
3517
+ * If this is a new scroll root, we want to remove all previous scrolls
3518
+ * from the viewport box.
3519
+ */
3520
+ if (isScrollRoot) {
3521
+ copyBoxInto(boxWithoutScroll, box);
3522
+ var rootScroll = this.root.scroll;
3523
+ /**
3524
+ * Undo the application of page scroll that was originally added
3525
+ * to the measured bounding box.
3526
+ */
3527
+ if (rootScroll) {
3528
+ translateAxis(boxWithoutScroll.x, -rootScroll.x);
3529
+ translateAxis(boxWithoutScroll.y, -rootScroll.y);
3530
+ }
3531
+ }
3515
3532
  translateAxis(boxWithoutScroll.x, scroll_1.x);
3516
3533
  translateAxis(boxWithoutScroll.y, scroll_1.y);
3517
3534
  }
@@ -7200,7 +7217,7 @@
7200
7217
  * and warn against mismatches.
7201
7218
  */
7202
7219
  {
7203
- warnOnce(nextValue.version === "6.3.14", "Attempting to mix Framer Motion versions ".concat(nextValue.version, " with 6.3.14 may not work as expected."));
7220
+ warnOnce(nextValue.version === "6.4.0", "Attempting to mix Framer Motion versions ".concat(nextValue.version, " with 6.4.0 may not work as expected."));
7204
7221
  }
7205
7222
  }
7206
7223
  else if (isMotionValue(prevValue)) {
@@ -8314,6 +8331,7 @@
8314
8331
  x: document.documentElement.scrollLeft || document.body.scrollLeft,
8315
8332
  y: document.documentElement.scrollTop || document.body.scrollTop,
8316
8333
  }); },
8334
+ checkIsScrollRoot: function () { return true; },
8317
8335
  });
8318
8336
 
8319
8337
  var rootProjectionNode = {
@@ -8336,6 +8354,9 @@
8336
8354
  resetTransform: function (instance, value) {
8337
8355
  instance.style.transform = value !== null && value !== void 0 ? value : "none";
8338
8356
  },
8357
+ checkIsScrollRoot: function (instance) {
8358
+ return Boolean(window.getComputedStyle(instance).position === "fixed");
8359
+ },
8339
8360
  });
8340
8361
 
8341
8362
  var featureBundle = __assign(__assign(__assign(__assign({}, animations), gestureAnimations), drag), layoutFeatures);
@@ -9398,6 +9419,96 @@
9398
9419
  return [item, runCycle];
9399
9420
  }
9400
9421
 
9422
+ function resolveElements(elements, selectorCache) {
9423
+ var _a;
9424
+ if (typeof elements === "string") {
9425
+ if (selectorCache) {
9426
+ (_a = selectorCache[elements]) !== null && _a !== void 0 ? _a : (selectorCache[elements] = document.querySelectorAll(elements));
9427
+ elements = selectorCache[elements];
9428
+ }
9429
+ else {
9430
+ elements = document.querySelectorAll(elements);
9431
+ }
9432
+ }
9433
+ else if (elements instanceof Element) {
9434
+ elements = [elements];
9435
+ }
9436
+ /**
9437
+ * Return an empty array
9438
+ */
9439
+ return Array.from(elements || []);
9440
+ }
9441
+
9442
+ const thresholds = {
9443
+ any: 0,
9444
+ all: 1,
9445
+ };
9446
+ function inView(elements, onStart, { root, margin: rootMargin, amount = "any" } = {}) {
9447
+ /**
9448
+ * If this browser doesn't support IntersectionObserver, return a dummy stop function.
9449
+ * Default triggering of onStart is tricky - it could be used for starting/stopping
9450
+ * videos, lazy loading content etc. We could provide an option to enable a fallback, or
9451
+ * provide a fallback callback option.
9452
+ */
9453
+ if (typeof IntersectionObserver === "undefined") {
9454
+ return () => { };
9455
+ }
9456
+ const resolvedElements = resolveElements(elements);
9457
+ const activeIntersections = new WeakMap();
9458
+ const onIntersectionChange = (entries) => {
9459
+ entries.forEach((entry) => {
9460
+ const onEnd = activeIntersections.get(entry.target);
9461
+ /**
9462
+ * If there's no change to the intersection, we don't need to
9463
+ * do anything here.
9464
+ */
9465
+ if (entry.isIntersecting === Boolean(onEnd))
9466
+ return;
9467
+ if (entry.isIntersecting) {
9468
+ const newOnEnd = onStart(entry);
9469
+ if (typeof newOnEnd === "function") {
9470
+ activeIntersections.set(entry.target, newOnEnd);
9471
+ }
9472
+ else {
9473
+ observer.unobserve(entry.target);
9474
+ }
9475
+ }
9476
+ else if (onEnd) {
9477
+ onEnd(entry);
9478
+ activeIntersections.delete(entry.target);
9479
+ }
9480
+ });
9481
+ };
9482
+ const observer = new IntersectionObserver(onIntersectionChange, {
9483
+ root,
9484
+ rootMargin,
9485
+ threshold: typeof amount === "number" ? amount : thresholds[amount],
9486
+ });
9487
+ resolvedElements.forEach((element) => observer.observe(element));
9488
+ return () => observer.disconnect();
9489
+ }
9490
+
9491
+ function useInView(ref, _a) {
9492
+ var _b = _a === void 0 ? {} : _a, root = _b.root, margin = _b.margin, amount = _b.amount, _c = _b.once, once = _c === void 0 ? false : _c;
9493
+ var _d = __read(React.useState(false), 2), isInView = _d[0], setInView = _d[1];
9494
+ React.useEffect(function () {
9495
+ var _a;
9496
+ if (!ref.current || (once && isInView))
9497
+ return;
9498
+ var onEnter = function () {
9499
+ setInView(true);
9500
+ return once ? undefined : function () { return setInView(false); };
9501
+ };
9502
+ var options = {
9503
+ root: (_a = root === null || root === void 0 ? void 0 : root.current) !== null && _a !== void 0 ? _a : undefined,
9504
+ margin: margin,
9505
+ amount: amount === "some" ? "any" : amount,
9506
+ };
9507
+ return inView(ref.current, onEnter, options);
9508
+ }, [root, ref, margin, once]);
9509
+ return isInView;
9510
+ }
9511
+
9401
9512
  /**
9402
9513
  * Can manually trigger a drag gesture on one or more `drag`-enabled `motion` components.
9403
9514
  *
@@ -9671,6 +9782,7 @@
9671
9782
  exports.useDragControls = useDragControls;
9672
9783
  exports.useElementScroll = useElementScroll;
9673
9784
  exports.useForceUpdate = useForceUpdate;
9785
+ exports.useInView = useInView;
9674
9786
  exports.useInstantLayoutTransition = useInstantLayoutTransition;
9675
9787
  exports.useInstantTransition = useInstantTransition;
9676
9788
  exports.useIsPresent = useIsPresent;