framer-motion 12.4.3 → 12.4.4-alpha.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.
@@ -1,21 +1,20 @@
1
- import { invariant } from 'motion-utils';
2
1
  import { setDragLock } from 'motion-dom';
3
- import { PanSession } from '../pan/PanSession.mjs';
4
- import { isRefObject } from '../../utils/is-ref-object.mjs';
2
+ import { invariant } from 'motion-utils';
3
+ import { animateMotionValue } from '../../animation/interfaces/motion-value.mjs';
4
+ import { addDomEvent } from '../../events/add-dom-event.mjs';
5
5
  import { addPointerEvent } from '../../events/add-pointer-event.mjs';
6
- import { applyConstraints, calcRelativeConstraints, resolveDragElastic, rebaseAxisConstraints, calcViewportConstraints, calcOrigin, defaultElastic } from './utils/constraints.mjs';
7
- import { createBox } from '../../projection/geometry/models.mjs';
8
- import { eachAxis } from '../../projection/utils/each-axis.mjs';
9
- import { measurePageBox } from '../../projection/utils/measure.mjs';
10
6
  import { extractEventInfo } from '../../events/event-info.mjs';
11
7
  import { convertBoxToBoundingBox, convertBoundingBoxToBox } from '../../projection/geometry/conversion.mjs';
12
- import { addDomEvent } from '../../events/add-dom-event.mjs';
13
8
  import { calcLength } from '../../projection/geometry/delta-calc.mjs';
9
+ import { createBox } from '../../projection/geometry/models.mjs';
10
+ import { eachAxis } from '../../projection/utils/each-axis.mjs';
11
+ import { measurePageBox } from '../../projection/utils/measure.mjs';
12
+ import { isRefObject } from '../../utils/is-ref-object.mjs';
14
13
  import { mixNumber } from '../../utils/mix/number.mjs';
15
14
  import { percent } from '../../value/types/numbers/units.mjs';
16
- import { animateMotionValue } from '../../animation/interfaces/motion-value.mjs';
17
- import { getContextWindow } from '../../utils/get-context-window.mjs';
18
15
  import { addValueToWillChange } from '../../value/use-will-change/add-will-change.mjs';
16
+ import { PanSession } from '../pan/PanSession.mjs';
17
+ import { applyConstraints, calcRelativeConstraints, resolveDragElastic, rebaseAxisConstraints, calcViewportConstraints, calcOrigin, defaultElastic } from './utils/constraints.mjs';
19
18
  import { frame } from '../../frameloop/frame.mjs';
20
19
 
21
20
  const elementDragControls = new WeakMap();
@@ -150,7 +149,6 @@ class VisualElementDragControls {
150
149
  }, {
151
150
  transformPagePoint: this.visualElement.getTransformPagePoint(),
152
151
  dragSnapToOrigin,
153
- contextWindow: getContextWindow(this.visualElement),
154
152
  });
155
153
  }
156
154
  stop(event, info) {
@@ -10,7 +10,7 @@ import { frame, cancelFrame, frameData } from '../../frameloop/frame.mjs';
10
10
  * @internal
11
11
  */
12
12
  class PanSession {
13
- constructor(event, handlers, { transformPagePoint, contextWindow, dragSnapToOrigin = false, } = {}) {
13
+ constructor(event, handlers, { transformPagePoint, dragSnapToOrigin = false } = {}) {
14
14
  /**
15
15
  * @internal
16
16
  */
@@ -27,10 +27,6 @@ class PanSession {
27
27
  * @internal
28
28
  */
29
29
  this.handlers = {};
30
- /**
31
- * @internal
32
- */
33
- this.contextWindow = window;
34
30
  this.updatePoint = () => {
35
31
  if (!(this.lastMoveEvent && this.lastMoveEventInfo))
36
32
  return;
@@ -53,19 +49,31 @@ class PanSession {
53
49
  onMove && onMove(this.lastMoveEvent, info);
54
50
  };
55
51
  this.handlePointerMove = (event, info) => {
52
+ if (event.currentTarget instanceof Element &&
53
+ event.currentTarget.hasPointerCapture &&
54
+ event.pointerId !== undefined) {
55
+ try {
56
+ if (!event.currentTarget.hasPointerCapture(event.pointerId)) {
57
+ return;
58
+ }
59
+ }
60
+ catch (e) { }
61
+ }
56
62
  this.lastMoveEvent = event;
57
63
  this.lastMoveEventInfo = transformPoint(info, this.transformPagePoint);
58
64
  // Throttle mouse move event to once per frame
59
65
  frame.update(this.updatePoint, true);
60
66
  };
61
67
  this.handlePointerUp = (event, info) => {
68
+ capturePointer(event, "release");
62
69
  this.end();
63
70
  const { onEnd, onSessionEnd, resumeAnimation } = this.handlers;
64
71
  if (this.dragSnapToOrigin)
65
72
  resumeAnimation && resumeAnimation();
66
73
  if (!(this.lastMoveEvent && this.lastMoveEventInfo))
67
74
  return;
68
- const panInfo = getPanInfo(event.type === "pointercancel"
75
+ const panInfo = getPanInfo(event.type === "pointercancel" ||
76
+ event.type === "lostpointercapture"
69
77
  ? this.lastMoveEventInfo
70
78
  : transformPoint(info, this.transformPagePoint), this.history);
71
79
  if (this.startEvent && onEnd) {
@@ -79,7 +87,6 @@ class PanSession {
79
87
  this.dragSnapToOrigin = dragSnapToOrigin;
80
88
  this.handlers = handlers;
81
89
  this.transformPagePoint = transformPagePoint;
82
- this.contextWindow = contextWindow || window;
83
90
  const info = extractEventInfo(event);
84
91
  const initialInfo = transformPoint(info, this.transformPagePoint);
85
92
  const { point } = initialInfo;
@@ -88,7 +95,8 @@ class PanSession {
88
95
  const { onSessionStart } = handlers;
89
96
  onSessionStart &&
90
97
  onSessionStart(event, getPanInfo(initialInfo, this.history));
91
- this.removeListeners = pipe(addPointerEvent(this.contextWindow, "pointermove", this.handlePointerMove), addPointerEvent(this.contextWindow, "pointerup", this.handlePointerUp), addPointerEvent(this.contextWindow, "pointercancel", this.handlePointerUp));
98
+ capturePointer(event, "set");
99
+ this.removeListeners = pipe(addPointerEvent(event.currentTarget, "pointermove", this.handlePointerMove), addPointerEvent(event.currentTarget, "pointerup", this.handlePointerUp), addPointerEvent(event.currentTarget, "pointercancel", this.handlePointerUp), addPointerEvent(event.currentTarget, "lostpointercapture", this.handlePointerUp));
92
100
  }
93
101
  updateHandlers(handlers) {
94
102
  this.handlers = handlers;
@@ -152,5 +160,16 @@ function getVelocity(history, timeDelta) {
152
160
  }
153
161
  return currentVelocity;
154
162
  }
163
+ function capturePointer(event, action) {
164
+ const actionName = `${action}PointerCapture`;
165
+ if (event.currentTarget instanceof Element &&
166
+ actionName in event.currentTarget &&
167
+ event.pointerId !== undefined) {
168
+ try {
169
+ event.currentTarget[actionName](event.pointerId);
170
+ }
171
+ catch (e) { }
172
+ }
173
+ }
155
174
 
156
175
  export { PanSession };
@@ -1,8 +1,7 @@
1
- import { PanSession } from './PanSession.mjs';
1
+ import { noop } from 'motion-utils';
2
2
  import { addPointerEvent } from '../../events/add-pointer-event.mjs';
3
3
  import { Feature } from '../../motion/features/Feature.mjs';
4
- import { noop } from 'motion-utils';
5
- import { getContextWindow } from '../../utils/get-context-window.mjs';
4
+ import { PanSession } from './PanSession.mjs';
6
5
  import { frame } from '../../frameloop/frame.mjs';
7
6
 
8
7
  const asyncHandler = (handler) => (event, info) => {
@@ -18,7 +17,6 @@ class PanGesture extends Feature {
18
17
  onPointerDown(pointerDownEvent) {
19
18
  this.session = new PanSession(pointerDownEvent, this.createPanHandlers(), {
20
19
  transformPagePoint: this.node.getTransformPagePoint(),
21
- contextWindow: getContextWindow(this.node),
22
20
  });
23
21
  }
24
22
  createPanHandlers() {
@@ -17,7 +17,7 @@ function updateMotionValuesFromProps(element, next, prev) {
17
17
  * and warn against mismatches.
18
18
  */
19
19
  if (process.env.NODE_ENV === "development") {
20
- warnOnce(nextValue.version === "12.4.3", `Attempting to mix Motion versions ${nextValue.version} with 12.4.3 may not work as expected.`);
20
+ warnOnce(nextValue.version === "12.4.4-alpha.0", `Attempting to mix Motion versions ${nextValue.version} with 12.4.4-alpha.0 may not work as expected.`);
21
21
  }
22
22
  }
23
23
  else if (isMotionValue(prevValue)) {
@@ -34,7 +34,7 @@ class MotionValue {
34
34
  * This will be replaced by the build step with the latest version number.
35
35
  * When MotionValues are provided to motion components, warn if versions are mixed.
36
36
  */
37
- this.version = "12.4.3";
37
+ this.version = "12.4.4-alpha.0";
38
38
  /**
39
39
  * Tracks whether this value can output a velocity. Currently this is only true
40
40
  * if the value is numerical, but we might be able to widen the scope here and support
@@ -466,7 +466,7 @@
466
466
 
467
467
  function resolveElements(elementOrSelector, scope, selectorCache) {
468
468
  var _a;
469
- if (elementOrSelector instanceof Element) {
469
+ if (elementOrSelector instanceof EventTarget) {
470
470
  return [elementOrSelector];
471
471
  }
472
472
  else if (typeof elementOrSelector === "string") {
@@ -641,46 +641,87 @@
641
641
  *
642
642
  * @public
643
643
  */
644
- function press(elementOrSelector, onPressStart, options = {}) {
645
- const [elements, eventOptions, cancelEvents] = setupGesture(elementOrSelector, options);
644
+ function press(targetOrSelector, onPressStart, options = {}) {
645
+ const [targets, eventOptions, cancelEvents] = setupGesture(targetOrSelector, options);
646
646
  const startPress = (startEvent) => {
647
- const element = startEvent.currentTarget;
648
- if (!isValidPressEvent(startEvent) || isPressing.has(element))
647
+ const target = startEvent.currentTarget;
648
+ if (!target || !isValidPressEvent(startEvent) || isPressing.has(target))
649
649
  return;
650
- isPressing.add(element);
651
- const onPressEnd = onPressStart(element, startEvent);
650
+ isPressing.add(target);
651
+ if (target.setPointerCapture && startEvent.pointerId !== undefined) {
652
+ try {
653
+ target.setPointerCapture(startEvent.pointerId);
654
+ }
655
+ catch (e) { }
656
+ }
657
+ const onPressEnd = onPressStart(target, startEvent);
652
658
  const onPointerEnd = (endEvent, success) => {
653
- window.removeEventListener("pointerup", onPointerUp);
654
- window.removeEventListener("pointercancel", onPointerCancel);
655
- if (!isValidPressEvent(endEvent) || !isPressing.has(element)) {
659
+ target.removeEventListener("pointerup", onPointerUp);
660
+ target.removeEventListener("pointercancel", onPointerCancel);
661
+ if (target.releasePointerCapture &&
662
+ endEvent.pointerId !== undefined) {
663
+ try {
664
+ target.releasePointerCapture(endEvent.pointerId);
665
+ }
666
+ catch (e) { }
667
+ }
668
+ if (!isValidPressEvent(endEvent) || !isPressing.has(target)) {
656
669
  return;
657
670
  }
658
- isPressing.delete(element);
671
+ isPressing.delete(target);
659
672
  if (typeof onPressEnd === "function") {
660
673
  onPressEnd(endEvent, { success });
661
674
  }
662
675
  };
663
676
  const onPointerUp = (upEvent) => {
664
- onPointerEnd(upEvent, options.useGlobalTarget ||
665
- isNodeOrChild(element, upEvent.target));
677
+ const isOutside = !upEvent.isTrusted
678
+ ? false
679
+ : checkOutside(upEvent, target instanceof Element
680
+ ? target.getBoundingClientRect()
681
+ : {
682
+ left: 0,
683
+ top: 0,
684
+ right: window.innerWidth,
685
+ bottom: window.innerHeight,
686
+ });
687
+ if (isOutside) {
688
+ onPointerEnd(upEvent, false);
689
+ }
690
+ else {
691
+ onPointerEnd(upEvent, !(target instanceof Element) ||
692
+ isNodeOrChild(target, upEvent.target));
693
+ }
666
694
  };
667
695
  const onPointerCancel = (cancelEvent) => {
668
696
  onPointerEnd(cancelEvent, false);
669
697
  };
670
- window.addEventListener("pointerup", onPointerUp, eventOptions);
671
- window.addEventListener("pointercancel", onPointerCancel, eventOptions);
698
+ target.addEventListener("pointerup", onPointerUp, eventOptions);
699
+ target.addEventListener("pointercancel", onPointerCancel, eventOptions);
700
+ target.addEventListener("lostpointercapture", onPointerCancel, eventOptions);
672
701
  };
673
- elements.forEach((element) => {
674
- if (!isElementKeyboardAccessible(element) &&
675
- element.getAttribute("tabindex") === null) {
676
- element.tabIndex = 0;
702
+ targets.forEach((target) => {
703
+ target = options.useGlobalTarget ? window : target;
704
+ let canAddKeyboardAccessibility = false;
705
+ if (target instanceof HTMLElement) {
706
+ canAddKeyboardAccessibility = true;
707
+ if (!isElementKeyboardAccessible(target) &&
708
+ target.getAttribute("tabindex") === null) {
709
+ target.tabIndex = 0;
710
+ }
677
711
  }
678
- const target = options.useGlobalTarget ? window : element;
679
712
  target.addEventListener("pointerdown", startPress, eventOptions);
680
- element.addEventListener("focus", (event) => enableKeyboardPress(event, eventOptions), eventOptions);
713
+ if (canAddKeyboardAccessibility) {
714
+ target.addEventListener("focus", (event) => enableKeyboardPress(event, eventOptions), eventOptions);
715
+ }
681
716
  });
682
717
  return cancelEvents;
683
718
  }
719
+ function checkOutside(event, rect) {
720
+ return (event.clientX < rect.left ||
721
+ event.clientX > rect.right ||
722
+ event.clientY < rect.top ||
723
+ event.clientY > rect.bottom);
724
+ }
684
725
 
685
726
  function setDragLock(axis) {
686
727
  if (axis === "x" || axis === "y") {
@@ -1064,7 +1105,7 @@
1064
1105
  * This will be replaced by the build step with the latest version number.
1065
1106
  * When MotionValues are provided to motion components, warn if versions are mixed.
1066
1107
  */
1067
- this.version = "12.4.3";
1108
+ this.version = "12.4.4-alpha.0";
1068
1109
  /**
1069
1110
  * Tracks whether this value can output a velocity. Currently this is only true
1070
1111
  * if the value is numerical, but we might be able to widen the scope here and support
@@ -5915,7 +5956,7 @@
5915
5956
  * and warn against mismatches.
5916
5957
  */
5917
5958
  {
5918
- warnOnce(nextValue.version === "12.4.3", `Attempting to mix Motion versions ${nextValue.version} with 12.4.3 may not work as expected.`);
5959
+ warnOnce(nextValue.version === "12.4.4-alpha.0", `Attempting to mix Motion versions ${nextValue.version} with 12.4.4-alpha.0 may not work as expected.`);
5919
5960
  }
5920
5961
  }
5921
5962
  else if (isMotionValue(prevValue)) {
@@ -10239,11 +10280,17 @@
10239
10280
  });
10240
10281
  }
10241
10282
 
10283
+ function isRefObject(ref) {
10284
+ return (ref &&
10285
+ typeof ref === "object" &&
10286
+ Object.prototype.hasOwnProperty.call(ref, "current"));
10287
+ }
10288
+
10242
10289
  /**
10243
10290
  * @internal
10244
10291
  */
10245
10292
  class PanSession {
10246
- constructor(event, handlers, { transformPagePoint, contextWindow, dragSnapToOrigin = false, } = {}) {
10293
+ constructor(event, handlers, { transformPagePoint, dragSnapToOrigin = false } = {}) {
10247
10294
  /**
10248
10295
  * @internal
10249
10296
  */
@@ -10260,10 +10307,6 @@
10260
10307
  * @internal
10261
10308
  */
10262
10309
  this.handlers = {};
10263
- /**
10264
- * @internal
10265
- */
10266
- this.contextWindow = window;
10267
10310
  this.updatePoint = () => {
10268
10311
  if (!(this.lastMoveEvent && this.lastMoveEventInfo))
10269
10312
  return;
@@ -10286,19 +10329,31 @@
10286
10329
  onMove && onMove(this.lastMoveEvent, info);
10287
10330
  };
10288
10331
  this.handlePointerMove = (event, info) => {
10332
+ if (event.currentTarget instanceof Element &&
10333
+ event.currentTarget.hasPointerCapture &&
10334
+ event.pointerId !== undefined) {
10335
+ try {
10336
+ if (!event.currentTarget.hasPointerCapture(event.pointerId)) {
10337
+ return;
10338
+ }
10339
+ }
10340
+ catch (e) { }
10341
+ }
10289
10342
  this.lastMoveEvent = event;
10290
10343
  this.lastMoveEventInfo = transformPoint(info, this.transformPagePoint);
10291
10344
  // Throttle mouse move event to once per frame
10292
10345
  frame.update(this.updatePoint, true);
10293
10346
  };
10294
10347
  this.handlePointerUp = (event, info) => {
10348
+ capturePointer(event, "release");
10295
10349
  this.end();
10296
10350
  const { onEnd, onSessionEnd, resumeAnimation } = this.handlers;
10297
10351
  if (this.dragSnapToOrigin)
10298
10352
  resumeAnimation && resumeAnimation();
10299
10353
  if (!(this.lastMoveEvent && this.lastMoveEventInfo))
10300
10354
  return;
10301
- const panInfo = getPanInfo(event.type === "pointercancel"
10355
+ const panInfo = getPanInfo(event.type === "pointercancel" ||
10356
+ event.type === "lostpointercapture"
10302
10357
  ? this.lastMoveEventInfo
10303
10358
  : transformPoint(info, this.transformPagePoint), this.history);
10304
10359
  if (this.startEvent && onEnd) {
@@ -10312,7 +10367,6 @@
10312
10367
  this.dragSnapToOrigin = dragSnapToOrigin;
10313
10368
  this.handlers = handlers;
10314
10369
  this.transformPagePoint = transformPagePoint;
10315
- this.contextWindow = contextWindow || window;
10316
10370
  const info = extractEventInfo(event);
10317
10371
  const initialInfo = transformPoint(info, this.transformPagePoint);
10318
10372
  const { point } = initialInfo;
@@ -10321,7 +10375,8 @@
10321
10375
  const { onSessionStart } = handlers;
10322
10376
  onSessionStart &&
10323
10377
  onSessionStart(event, getPanInfo(initialInfo, this.history));
10324
- this.removeListeners = pipe(addPointerEvent(this.contextWindow, "pointermove", this.handlePointerMove), addPointerEvent(this.contextWindow, "pointerup", this.handlePointerUp), addPointerEvent(this.contextWindow, "pointercancel", this.handlePointerUp));
10378
+ capturePointer(event, "set");
10379
+ this.removeListeners = pipe(addPointerEvent(event.currentTarget, "pointermove", this.handlePointerMove), addPointerEvent(event.currentTarget, "pointerup", this.handlePointerUp), addPointerEvent(event.currentTarget, "pointercancel", this.handlePointerUp), addPointerEvent(event.currentTarget, "lostpointercapture", this.handlePointerUp));
10325
10380
  }
10326
10381
  updateHandlers(handlers) {
10327
10382
  this.handlers = handlers;
@@ -10385,11 +10440,16 @@
10385
10440
  }
10386
10441
  return currentVelocity;
10387
10442
  }
10388
-
10389
- function isRefObject(ref) {
10390
- return (ref &&
10391
- typeof ref === "object" &&
10392
- Object.prototype.hasOwnProperty.call(ref, "current"));
10443
+ function capturePointer(event, action) {
10444
+ const actionName = `${action}PointerCapture`;
10445
+ if (event.currentTarget instanceof Element &&
10446
+ actionName in event.currentTarget &&
10447
+ event.pointerId !== undefined) {
10448
+ try {
10449
+ event.currentTarget[actionName](event.pointerId);
10450
+ }
10451
+ catch (e) { }
10452
+ }
10393
10453
  }
10394
10454
 
10395
10455
  /**
@@ -10515,11 +10575,6 @@
10515
10575
  : dragElastic[label] || 0;
10516
10576
  }
10517
10577
 
10518
- // Fixes https://github.com/motiondivision/motion/issues/2270
10519
- const getContextWindow = ({ current }) => {
10520
- return current ? current.ownerDocument.defaultView : null;
10521
- };
10522
-
10523
10578
  const elementDragControls = new WeakMap();
10524
10579
  /**
10525
10580
  *
@@ -10652,7 +10707,6 @@
10652
10707
  }, {
10653
10708
  transformPagePoint: this.visualElement.getTransformPagePoint(),
10654
10709
  dragSnapToOrigin,
10655
- contextWindow: getContextWindow(this.visualElement),
10656
10710
  });
10657
10711
  }
10658
10712
  stop(event, info) {
@@ -11018,7 +11072,6 @@
11018
11072
  onPointerDown(pointerDownEvent) {
11019
11073
  this.session = new PanSession(pointerDownEvent, this.createPanHandlers(), {
11020
11074
  transformPagePoint: this.node.getTransformPagePoint(),
11021
- contextWindow: getContextWindow(this.node),
11022
11075
  });
11023
11076
  }
11024
11077
  createPanHandlers() {