motion 12.4.3 → 12.4.4

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.
@@ -363,7 +363,7 @@ function mapEasingToNativeEasing(easing, duration) {
363
363
 
364
364
  function resolveElements(elementOrSelector, scope, selectorCache) {
365
365
  var _a;
366
- if (elementOrSelector instanceof Element) {
366
+ if (elementOrSelector instanceof EventTarget) {
367
367
  return [elementOrSelector];
368
368
  }
369
369
  else if (typeof elementOrSelector === "string") {
@@ -1,21 +1,20 @@
1
1
  import { invariant } from '../../../../../motion-utils/dist/es/errors.mjs';
2
2
  import { setDragLock } from '../../../../../motion-dom/dist/es/gestures/drag/state/set-active.mjs';
3
- import { PanSession } from '../pan/PanSession.mjs';
4
- import { isRefObject } from '../../utils/is-ref-object.mjs';
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, calcViewportConstraints, rebaseAxisConstraints, 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, calcViewportConstraints, rebaseAxisConstraints, 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) {
@@ -11,7 +11,7 @@ import { frame, cancelFrame, frameData } from '../../frameloop/frame.mjs';
11
11
  * @internal
12
12
  */
13
13
  class PanSession {
14
- constructor(event, handlers, { transformPagePoint, contextWindow, dragSnapToOrigin = false, } = {}) {
14
+ constructor(event, handlers, { transformPagePoint, dragSnapToOrigin = false } = {}) {
15
15
  /**
16
16
  * @internal
17
17
  */
@@ -28,10 +28,6 @@ class PanSession {
28
28
  * @internal
29
29
  */
30
30
  this.handlers = {};
31
- /**
32
- * @internal
33
- */
34
- this.contextWindow = window;
35
31
  this.updatePoint = () => {
36
32
  if (!(this.lastMoveEvent && this.lastMoveEventInfo))
37
33
  return;
@@ -54,19 +50,31 @@ class PanSession {
54
50
  onMove && onMove(this.lastMoveEvent, info);
55
51
  };
56
52
  this.handlePointerMove = (event, info) => {
53
+ if (event.currentTarget instanceof Element &&
54
+ event.currentTarget.hasPointerCapture &&
55
+ event.pointerId !== undefined) {
56
+ try {
57
+ if (!event.currentTarget.hasPointerCapture(event.pointerId)) {
58
+ return;
59
+ }
60
+ }
61
+ catch (e) { }
62
+ }
57
63
  this.lastMoveEvent = event;
58
64
  this.lastMoveEventInfo = transformPoint(info, this.transformPagePoint);
59
65
  // Throttle mouse move event to once per frame
60
66
  frame.update(this.updatePoint, true);
61
67
  };
62
68
  this.handlePointerUp = (event, info) => {
69
+ capturePointer(event, "release");
63
70
  this.end();
64
71
  const { onEnd, onSessionEnd, resumeAnimation } = this.handlers;
65
72
  if (this.dragSnapToOrigin)
66
73
  resumeAnimation && resumeAnimation();
67
74
  if (!(this.lastMoveEvent && this.lastMoveEventInfo))
68
75
  return;
69
- const panInfo = getPanInfo(event.type === "pointercancel"
76
+ const panInfo = getPanInfo(event.type === "pointercancel" ||
77
+ event.type === "lostpointercapture"
70
78
  ? this.lastMoveEventInfo
71
79
  : transformPoint(info, this.transformPagePoint), this.history);
72
80
  if (this.startEvent && onEnd) {
@@ -80,7 +88,6 @@ class PanSession {
80
88
  this.dragSnapToOrigin = dragSnapToOrigin;
81
89
  this.handlers = handlers;
82
90
  this.transformPagePoint = transformPagePoint;
83
- this.contextWindow = contextWindow || window;
84
91
  const info = extractEventInfo(event);
85
92
  const initialInfo = transformPoint(info, this.transformPagePoint);
86
93
  const { point } = initialInfo;
@@ -89,7 +96,8 @@ class PanSession {
89
96
  const { onSessionStart } = handlers;
90
97
  onSessionStart &&
91
98
  onSessionStart(event, getPanInfo(initialInfo, this.history));
92
- this.removeListeners = pipe(addPointerEvent(this.contextWindow, "pointermove", this.handlePointerMove), addPointerEvent(this.contextWindow, "pointerup", this.handlePointerUp), addPointerEvent(this.contextWindow, "pointercancel", this.handlePointerUp));
99
+ capturePointer(event, "set");
100
+ 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));
93
101
  }
94
102
  updateHandlers(handlers) {
95
103
  this.handlers = handlers;
@@ -153,5 +161,16 @@ function getVelocity(history, timeDelta) {
153
161
  }
154
162
  return currentVelocity;
155
163
  }
164
+ function capturePointer(event, action) {
165
+ const actionName = `${action}PointerCapture`;
166
+ if (event.currentTarget instanceof Element &&
167
+ actionName in event.currentTarget &&
168
+ event.pointerId !== undefined) {
169
+ try {
170
+ event.currentTarget[actionName](event.pointerId);
171
+ }
172
+ catch (e) { }
173
+ }
174
+ }
156
175
 
157
176
  export { PanSession };
@@ -1,9 +1,8 @@
1
- import { PanSession } from './PanSession.mjs';
2
- import { addPointerEvent } from '../../events/add-pointer-event.mjs';
3
- import { Feature } from '../../motion/features/Feature.mjs';
4
1
  import '../../../../../motion-utils/dist/es/errors.mjs';
5
2
  import { noop } from '../../../../../motion-utils/dist/es/noop.mjs';
6
- import { getContextWindow } from '../../utils/get-context-window.mjs';
3
+ import { addPointerEvent } from '../../events/add-pointer-event.mjs';
4
+ import { Feature } from '../../motion/features/Feature.mjs';
5
+ import { PanSession } from './PanSession.mjs';
7
6
  import { frame } from '../../frameloop/frame.mjs';
8
7
 
9
8
  const asyncHandler = (handler) => (event, info) => {
@@ -19,7 +18,6 @@ class PanGesture extends Feature {
19
18
  onPointerDown(pointerDownEvent) {
20
19
  this.session = new PanSession(pointerDownEvent, this.createPanHandlers(), {
21
20
  transformPagePoint: this.node.getTransformPagePoint(),
22
- contextWindow: getContextWindow(this.node),
23
21
  });
24
22
  }
25
23
  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", `Attempting to mix Motion versions ${nextValue.version} with 12.4.4 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";
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
@@ -32,45 +32,86 @@ function isValidPressEvent(event) {
32
32
  *
33
33
  * @public
34
34
  */
35
- function press(elementOrSelector, onPressStart, options = {}) {
36
- const [elements, eventOptions, cancelEvents] = setupGesture(elementOrSelector, options);
35
+ function press(targetOrSelector, onPressStart, options = {}) {
36
+ const [targets, eventOptions, cancelEvents] = setupGesture(targetOrSelector, options);
37
37
  const startPress = (startEvent) => {
38
- const element = startEvent.currentTarget;
39
- if (!isValidPressEvent(startEvent) || isPressing.has(element))
38
+ const target = startEvent.currentTarget;
39
+ if (!target || !isValidPressEvent(startEvent) || isPressing.has(target))
40
40
  return;
41
- isPressing.add(element);
42
- const onPressEnd = onPressStart(element, startEvent);
41
+ isPressing.add(target);
42
+ if (target.setPointerCapture && startEvent.pointerId !== undefined) {
43
+ try {
44
+ target.setPointerCapture(startEvent.pointerId);
45
+ }
46
+ catch (e) { }
47
+ }
48
+ const onPressEnd = onPressStart(target, startEvent);
43
49
  const onPointerEnd = (endEvent, success) => {
44
- window.removeEventListener("pointerup", onPointerUp);
45
- window.removeEventListener("pointercancel", onPointerCancel);
46
- if (!isValidPressEvent(endEvent) || !isPressing.has(element)) {
50
+ target.removeEventListener("pointerup", onPointerUp);
51
+ target.removeEventListener("pointercancel", onPointerCancel);
52
+ if (target.releasePointerCapture &&
53
+ endEvent.pointerId !== undefined) {
54
+ try {
55
+ target.releasePointerCapture(endEvent.pointerId);
56
+ }
57
+ catch (e) { }
58
+ }
59
+ if (!isValidPressEvent(endEvent) || !isPressing.has(target)) {
47
60
  return;
48
61
  }
49
- isPressing.delete(element);
62
+ isPressing.delete(target);
50
63
  if (typeof onPressEnd === "function") {
51
64
  onPressEnd(endEvent, { success });
52
65
  }
53
66
  };
54
67
  const onPointerUp = (upEvent) => {
55
- onPointerEnd(upEvent, options.useGlobalTarget ||
56
- isNodeOrChild(element, upEvent.target));
68
+ const isOutside = !upEvent.isTrusted
69
+ ? false
70
+ : checkOutside(upEvent, target instanceof Element
71
+ ? target.getBoundingClientRect()
72
+ : {
73
+ left: 0,
74
+ top: 0,
75
+ right: window.innerWidth,
76
+ bottom: window.innerHeight,
77
+ });
78
+ if (isOutside) {
79
+ onPointerEnd(upEvent, false);
80
+ }
81
+ else {
82
+ onPointerEnd(upEvent, !(target instanceof Element) ||
83
+ isNodeOrChild(target, upEvent.target));
84
+ }
57
85
  };
58
86
  const onPointerCancel = (cancelEvent) => {
59
87
  onPointerEnd(cancelEvent, false);
60
88
  };
61
- window.addEventListener("pointerup", onPointerUp, eventOptions);
62
- window.addEventListener("pointercancel", onPointerCancel, eventOptions);
89
+ target.addEventListener("pointerup", onPointerUp, eventOptions);
90
+ target.addEventListener("pointercancel", onPointerCancel, eventOptions);
91
+ target.addEventListener("lostpointercapture", onPointerCancel, eventOptions);
63
92
  };
64
- elements.forEach((element) => {
65
- if (!isElementKeyboardAccessible(element) &&
66
- element.getAttribute("tabindex") === null) {
67
- element.tabIndex = 0;
93
+ targets.forEach((target) => {
94
+ target = options.useGlobalTarget ? window : target;
95
+ let canAddKeyboardAccessibility = false;
96
+ if (target instanceof HTMLElement) {
97
+ canAddKeyboardAccessibility = true;
98
+ if (!isElementKeyboardAccessible(target) &&
99
+ target.getAttribute("tabindex") === null) {
100
+ target.tabIndex = 0;
101
+ }
68
102
  }
69
- const target = options.useGlobalTarget ? window : element;
70
103
  target.addEventListener("pointerdown", startPress, eventOptions);
71
- element.addEventListener("focus", (event) => enableKeyboardPress(event, eventOptions), eventOptions);
104
+ if (canAddKeyboardAccessibility) {
105
+ target.addEventListener("focus", (event) => enableKeyboardPress(event, eventOptions), eventOptions);
106
+ }
72
107
  });
73
108
  return cancelEvents;
74
109
  }
110
+ function checkOutside(event, rect) {
111
+ return (event.clientX < rect.left ||
112
+ event.clientX > rect.right ||
113
+ event.clientY < rect.top ||
114
+ event.clientY > rect.bottom);
115
+ }
75
116
 
76
117
  export { press };
@@ -1,6 +1,6 @@
1
1
  function resolveElements(elementOrSelector, scope, selectorCache) {
2
2
  var _a;
3
- if (elementOrSelector instanceof Element) {
3
+ if (elementOrSelector instanceof EventTarget) {
4
4
  return [elementOrSelector];
5
5
  }
6
6
  else if (typeof elementOrSelector === "string") {
@@ -366,7 +366,7 @@
366
366
 
367
367
  function resolveElements(elementOrSelector, scope, selectorCache) {
368
368
  var _a;
369
- if (elementOrSelector instanceof Element) {
369
+ if (elementOrSelector instanceof EventTarget) {
370
370
  return [elementOrSelector];
371
371
  }
372
372
  else if (typeof elementOrSelector === "string") {
@@ -541,46 +541,87 @@
541
541
  *
542
542
  * @public
543
543
  */
544
- function press(elementOrSelector, onPressStart, options = {}) {
545
- const [elements, eventOptions, cancelEvents] = setupGesture(elementOrSelector, options);
544
+ function press(targetOrSelector, onPressStart, options = {}) {
545
+ const [targets, eventOptions, cancelEvents] = setupGesture(targetOrSelector, options);
546
546
  const startPress = (startEvent) => {
547
- const element = startEvent.currentTarget;
548
- if (!isValidPressEvent(startEvent) || isPressing.has(element))
547
+ const target = startEvent.currentTarget;
548
+ if (!target || !isValidPressEvent(startEvent) || isPressing.has(target))
549
549
  return;
550
- isPressing.add(element);
551
- const onPressEnd = onPressStart(element, startEvent);
550
+ isPressing.add(target);
551
+ if (target.setPointerCapture && startEvent.pointerId !== undefined) {
552
+ try {
553
+ target.setPointerCapture(startEvent.pointerId);
554
+ }
555
+ catch (e) { }
556
+ }
557
+ const onPressEnd = onPressStart(target, startEvent);
552
558
  const onPointerEnd = (endEvent, success) => {
553
- window.removeEventListener("pointerup", onPointerUp);
554
- window.removeEventListener("pointercancel", onPointerCancel);
555
- if (!isValidPressEvent(endEvent) || !isPressing.has(element)) {
559
+ target.removeEventListener("pointerup", onPointerUp);
560
+ target.removeEventListener("pointercancel", onPointerCancel);
561
+ if (target.releasePointerCapture &&
562
+ endEvent.pointerId !== undefined) {
563
+ try {
564
+ target.releasePointerCapture(endEvent.pointerId);
565
+ }
566
+ catch (e) { }
567
+ }
568
+ if (!isValidPressEvent(endEvent) || !isPressing.has(target)) {
556
569
  return;
557
570
  }
558
- isPressing.delete(element);
571
+ isPressing.delete(target);
559
572
  if (typeof onPressEnd === "function") {
560
573
  onPressEnd(endEvent, { success });
561
574
  }
562
575
  };
563
576
  const onPointerUp = (upEvent) => {
564
- onPointerEnd(upEvent, options.useGlobalTarget ||
565
- isNodeOrChild(element, upEvent.target));
577
+ const isOutside = !upEvent.isTrusted
578
+ ? false
579
+ : checkOutside(upEvent, target instanceof Element
580
+ ? target.getBoundingClientRect()
581
+ : {
582
+ left: 0,
583
+ top: 0,
584
+ right: window.innerWidth,
585
+ bottom: window.innerHeight,
586
+ });
587
+ if (isOutside) {
588
+ onPointerEnd(upEvent, false);
589
+ }
590
+ else {
591
+ onPointerEnd(upEvent, !(target instanceof Element) ||
592
+ isNodeOrChild(target, upEvent.target));
593
+ }
566
594
  };
567
595
  const onPointerCancel = (cancelEvent) => {
568
596
  onPointerEnd(cancelEvent, false);
569
597
  };
570
- window.addEventListener("pointerup", onPointerUp, eventOptions);
571
- window.addEventListener("pointercancel", onPointerCancel, eventOptions);
598
+ target.addEventListener("pointerup", onPointerUp, eventOptions);
599
+ target.addEventListener("pointercancel", onPointerCancel, eventOptions);
600
+ target.addEventListener("lostpointercapture", onPointerCancel, eventOptions);
572
601
  };
573
- elements.forEach((element) => {
574
- if (!isElementKeyboardAccessible(element) &&
575
- element.getAttribute("tabindex") === null) {
576
- element.tabIndex = 0;
602
+ targets.forEach((target) => {
603
+ target = options.useGlobalTarget ? window : target;
604
+ let canAddKeyboardAccessibility = false;
605
+ if (target instanceof HTMLElement) {
606
+ canAddKeyboardAccessibility = true;
607
+ if (!isElementKeyboardAccessible(target) &&
608
+ target.getAttribute("tabindex") === null) {
609
+ target.tabIndex = 0;
610
+ }
577
611
  }
578
- const target = options.useGlobalTarget ? window : element;
579
612
  target.addEventListener("pointerdown", startPress, eventOptions);
580
- element.addEventListener("focus", (event) => enableKeyboardPress(event, eventOptions), eventOptions);
613
+ if (canAddKeyboardAccessibility) {
614
+ target.addEventListener("focus", (event) => enableKeyboardPress(event, eventOptions), eventOptions);
615
+ }
581
616
  });
582
617
  return cancelEvents;
583
618
  }
619
+ function checkOutside(event, rect) {
620
+ return (event.clientX < rect.left ||
621
+ event.clientX > rect.right ||
622
+ event.clientY < rect.top ||
623
+ event.clientY > rect.bottom);
624
+ }
584
625
 
585
626
  const clamp = (min, max, v) => {
586
627
  if (v > max)
@@ -1588,7 +1629,7 @@
1588
1629
  * This will be replaced by the build step with the latest version number.
1589
1630
  * When MotionValues are provided to motion components, warn if versions are mixed.
1590
1631
  */
1591
- this.version = "12.4.3";
1632
+ this.version = "12.4.4";
1592
1633
  /**
1593
1634
  * Tracks whether this value can output a velocity. Currently this is only true
1594
1635
  * if the value is numerical, but we might be able to widen the scope here and support
@@ -4523,7 +4564,7 @@
4523
4564
  * and warn against mismatches.
4524
4565
  */
4525
4566
  {
4526
- warnOnce(nextValue.version === "12.4.3", `Attempting to mix Motion versions ${nextValue.version} with 12.4.3 may not work as expected.`);
4567
+ warnOnce(nextValue.version === "12.4.4", `Attempting to mix Motion versions ${nextValue.version} with 12.4.4 may not work as expected.`);
4527
4568
  }
4528
4569
  }
4529
4570
  else if (isMotionValue(prevValue)) {