motion 12.0.0-alpha.2 → 12.0.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.
Files changed (157) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +7 -24
  3. package/dist/cjs/index.js +2792 -2446
  4. package/dist/cjs/mini.js +629 -193
  5. package/dist/cjs/react-client.js +3624 -3434
  6. package/dist/cjs/react-m.js +397 -351
  7. package/dist/cjs/react-mini.js +225 -191
  8. package/dist/es/framer-motion/dist/es/animation/animate/index.mjs +3 -2
  9. package/dist/es/framer-motion/dist/es/animation/animate/resolve-subjects.mjs +2 -1
  10. package/dist/es/framer-motion/dist/es/animation/animate/single-value.mjs +1 -1
  11. package/dist/es/framer-motion/dist/es/animation/animate/subject.mjs +1 -1
  12. package/dist/es/framer-motion/dist/es/animation/animators/AcceleratedAnimation.mjs +16 -12
  13. package/dist/es/framer-motion/dist/es/animation/animators/BaseAnimation.mjs +3 -2
  14. package/dist/es/framer-motion/dist/es/animation/animators/MainThreadAnimation.mjs +10 -10
  15. package/dist/es/framer-motion/dist/es/animation/animators/utils/can-animate.mjs +2 -2
  16. package/dist/es/framer-motion/dist/es/animation/animators/waapi/NativeAnimation.mjs +30 -89
  17. package/dist/es/framer-motion/dist/es/animation/animators/waapi/animate-elements.mjs +4 -4
  18. package/dist/es/framer-motion/dist/es/animation/animators/waapi/animate-sequence.mjs +14 -0
  19. package/dist/es/framer-motion/dist/es/animation/animators/waapi/animate-style.mjs +2 -1
  20. package/dist/es/framer-motion/dist/es/animation/animators/waapi/index.mjs +2 -1
  21. package/dist/es/framer-motion/dist/es/animation/animators/waapi/utils/supports-partial-keyframes.mjs +2 -1
  22. package/dist/es/framer-motion/dist/es/animation/animators/waapi/utils/supports-waapi.mjs +2 -1
  23. package/dist/es/framer-motion/dist/es/animation/generators/spring/defaults.mjs +27 -0
  24. package/dist/es/framer-motion/dist/es/animation/generators/spring/find.mjs +10 -13
  25. package/dist/es/framer-motion/dist/es/animation/generators/spring/index.mjs +57 -18
  26. package/dist/es/framer-motion/dist/es/animation/hooks/animation-controls.mjs +1 -1
  27. package/dist/es/framer-motion/dist/es/animation/interfaces/motion-value.mjs +7 -6
  28. package/dist/es/framer-motion/dist/es/animation/interfaces/visual-element-target.mjs +6 -5
  29. package/dist/es/framer-motion/dist/es/animation/optimized-appear/start.mjs +2 -1
  30. package/dist/es/framer-motion/dist/es/animation/optimized-appear/store-id.mjs +1 -1
  31. package/dist/es/framer-motion/dist/es/animation/sequence/create.mjs +32 -6
  32. package/dist/es/framer-motion/dist/es/animation/sequence/utils/calc-repeat-duration.mjs +5 -0
  33. package/dist/es/framer-motion/dist/es/animation/sequence/utils/normalize-times.mjs +13 -0
  34. package/dist/es/framer-motion/dist/es/animation/utils/default-transitions.mjs +1 -1
  35. package/dist/es/framer-motion/dist/es/components/AnimatePresence/index.mjs +10 -7
  36. package/dist/es/framer-motion/dist/es/components/AnimatePresence/use-presence.mjs +6 -3
  37. package/dist/es/framer-motion/dist/es/components/AnimateSharedLayout.mjs +1 -1
  38. package/dist/es/framer-motion/dist/es/components/Reorder/Group.mjs +1 -1
  39. package/dist/es/framer-motion/dist/es/components/Reorder/Item.mjs +1 -1
  40. package/dist/es/framer-motion/dist/es/easing/cubic-bezier.mjs +2 -1
  41. package/dist/es/framer-motion/dist/es/easing/utils/map.mjs +6 -6
  42. package/dist/es/framer-motion/dist/es/events/event-info.mjs +5 -4
  43. package/dist/es/framer-motion/dist/es/frameloop/frame.mjs +2 -1
  44. package/dist/es/framer-motion/dist/es/frameloop/render-step.mjs +3 -2
  45. package/dist/es/framer-motion/dist/es/gestures/drag/VisualElementDragControls.mjs +12 -15
  46. package/dist/es/framer-motion/dist/es/gestures/drag/index.mjs +2 -1
  47. package/dist/es/framer-motion/dist/es/gestures/drag/utils/constraints.mjs +2 -1
  48. package/dist/es/framer-motion/dist/es/gestures/hover.mjs +20 -22
  49. package/dist/es/framer-motion/dist/es/gestures/pan/PanSession.mjs +6 -5
  50. package/dist/es/framer-motion/dist/es/gestures/pan/index.mjs +2 -1
  51. package/dist/es/framer-motion/dist/es/gestures/press.mjs +20 -119
  52. package/dist/es/framer-motion/dist/es/motion/index.mjs +11 -7
  53. package/dist/es/framer-motion/dist/es/motion/utils/is-forced-motion-value.mjs +1 -1
  54. package/dist/es/framer-motion/dist/es/motion/utils/use-motion-ref.mjs +3 -1
  55. package/dist/es/framer-motion/dist/es/motion/utils/use-visual-element.mjs +1 -1
  56. package/dist/es/framer-motion/dist/es/motion/utils/use-visual-state.mjs +11 -5
  57. package/dist/es/framer-motion/dist/es/projection/animation/mix-values.mjs +3 -2
  58. package/dist/es/framer-motion/dist/es/projection/node/create-projection-node.mjs +15 -14
  59. package/dist/es/framer-motion/dist/es/render/VisualElement.mjs +15 -13
  60. package/dist/es/framer-motion/dist/es/render/dom/DOMKeyframesResolver.mjs +4 -3
  61. package/dist/es/framer-motion/dist/es/render/dom/DOMVisualElement.mjs +15 -0
  62. package/dist/es/framer-motion/dist/es/render/dom/resize/handle-element.mjs +2 -1
  63. package/dist/es/framer-motion/dist/es/render/dom/scroll/index.mjs +4 -4
  64. package/dist/es/framer-motion/dist/es/render/dom/scroll/info.mjs +2 -1
  65. package/dist/es/framer-motion/dist/es/render/dom/scroll/offsets/index.mjs +6 -5
  66. package/dist/es/framer-motion/dist/es/render/dom/utils/css-variables-conversion.mjs +1 -1
  67. package/dist/es/framer-motion/dist/es/render/dom/utils/unit-conversion.mjs +2 -14
  68. package/dist/es/framer-motion/dist/es/render/dom/viewport/index.mjs +4 -3
  69. package/dist/es/framer-motion/dist/es/render/html/HTMLVisualElement.mjs +6 -20
  70. package/dist/es/framer-motion/dist/es/render/html/utils/build-styles.mjs +2 -2
  71. package/dist/es/framer-motion/dist/es/render/html/utils/build-transform.mjs +1 -1
  72. package/dist/es/framer-motion/dist/es/render/html/utils/keys-position.mjs +13 -0
  73. package/dist/es/framer-motion/dist/es/render/svg/SVGVisualElement.mjs +6 -6
  74. package/dist/es/framer-motion/dist/es/render/svg/config-motion.mjs +57 -24
  75. package/dist/es/framer-motion/dist/es/render/svg/utils/build-attrs.mjs +1 -1
  76. package/dist/es/framer-motion/dist/es/render/svg/utils/scrape-motion-values.mjs +1 -1
  77. package/dist/es/framer-motion/dist/es/render/utils/motion-values.mjs +1 -1
  78. package/dist/es/framer-motion/dist/es/utils/delay.mjs +2 -1
  79. package/dist/es/framer-motion/dist/es/utils/get-context-window.mjs +1 -1
  80. package/dist/es/framer-motion/dist/es/utils/interpolate.mjs +8 -5
  81. package/dist/es/framer-motion/dist/es/utils/mix/color.mjs +1 -1
  82. package/dist/es/framer-motion/dist/es/utils/mix/complex.mjs +1 -1
  83. package/dist/es/framer-motion/dist/es/utils/offsets/fill.mjs +2 -1
  84. package/dist/es/framer-motion/dist/es/utils/use-instant-transition.mjs +1 -1
  85. package/dist/es/framer-motion/dist/es/value/index.mjs +2 -2
  86. package/dist/es/framer-motion/dist/es/value/use-inverted-scale.mjs +1 -1
  87. package/dist/es/framer-motion/dist/es/value/use-scroll.mjs +1 -1
  88. package/dist/es/framer-motion/dist/es/value/use-spring.mjs +3 -3
  89. package/dist/es/framer-motion/dist/es/value/use-will-change/get-will-change-name.mjs +1 -1
  90. package/dist/es/motion/lib/index.mjs +12 -7
  91. package/dist/es/motion/lib/mini.mjs +1 -0
  92. package/dist/es/motion/lib/react.mjs +41 -37
  93. package/dist/es/{framer-motion/dist/es/animation/GroupPlaybackControls.mjs → motion-dom/dist/es/animation/controls/BaseGroup.mjs} +7 -6
  94. package/dist/es/motion-dom/dist/es/animation/controls/Group.mjs +13 -0
  95. package/dist/es/{framer-motion/dist/es/easing → motion-dom/dist/es/animation/generators}/utils/create-generator-easing.mjs +6 -3
  96. package/dist/es/motion-dom/dist/es/animation/waapi/NativeAnimationControls.mjs +85 -0
  97. package/dist/es/{framer-motion/dist/es/animation/animators/waapi → motion-dom/dist/es/animation/waapi/utils}/easing.mjs +3 -3
  98. package/dist/es/{framer-motion/dist/es/animation/animators → motion-dom/dist/es/animation}/waapi/utils/linear.mjs +4 -4
  99. package/dist/es/motion-dom/dist/es/gestures/drag/state/is-active.mjs +9 -0
  100. package/dist/es/motion-dom/dist/es/gestures/drag/state/set-active.mjs +28 -0
  101. package/dist/es/motion-dom/dist/es/gestures/hover.mjs +37 -0
  102. package/dist/es/motion-dom/dist/es/gestures/press/index.mjs +76 -0
  103. package/dist/es/motion-dom/dist/es/gestures/press/utils/is-keyboard-accessible.mjs +13 -0
  104. package/dist/es/motion-dom/dist/es/gestures/press/utils/keyboard.mjs +38 -0
  105. package/dist/es/motion-dom/dist/es/gestures/press/utils/state.mjs +3 -0
  106. package/dist/es/motion-dom/dist/es/gestures/utils/setup.mjs +15 -0
  107. package/dist/es/motion-dom/dist/es/utils/resolve-elements.mjs +22 -0
  108. package/dist/es/{framer-motion/dist/es/animation/animators/waapi/utils/supports-linear-easing.mjs → motion-dom/dist/es/utils/supports/linear-easing.mjs} +1 -1
  109. package/dist/es/{framer-motion/dist/es/animation/animators/waapi/utils/memo-supports.mjs → motion-dom/dist/es/utils/supports/memo.mjs} +3 -2
  110. package/dist/es/motion-dom/dist/es/utils/supports/scroll-timeline.mjs +6 -0
  111. package/dist/es/{framer-motion/dist/es/utils → motion-utils/dist/es}/memo.mjs +1 -0
  112. package/dist/es/{framer-motion/dist/es/utils → motion-utils/dist/es}/noop.mjs +1 -0
  113. package/dist/es/{framer-motion/dist/es/utils → motion-utils/dist/es}/progress.mjs +1 -0
  114. package/dist/es/{framer-motion/dist/es/utils → motion-utils/dist/es}/time-conversion.mjs +2 -0
  115. package/dist/motion.dev.js +2792 -2446
  116. package/dist/motion.js +1 -1
  117. package/package.json +6 -6
  118. package/.turbo/turbo-build.log +0 -47
  119. package/dist/es/framer-motion/dist/es/gestures/drag/utils/lock.mjs +0 -53
  120. package/dist/es/framer-motion/dist/es/render/dom/scroll/supports.mjs +0 -5
  121. package/dist/es/framer-motion/dist/es/render/dom/utils/resolve-element.mjs +0 -28
  122. package/lib/index.js +0 -2
  123. package/lib/index.js.map +0 -1
  124. package/lib/mini.js +0 -2
  125. package/lib/mini.js.map +0 -1
  126. package/lib/react-client.js +0 -3
  127. package/lib/react-client.js.map +0 -1
  128. package/lib/react-m.js +0 -3
  129. package/lib/react-m.js.map +0 -1
  130. package/lib/react-mini.js +0 -3
  131. package/lib/react-mini.js.map +0 -1
  132. package/lib/react.js +0 -3
  133. package/lib/react.js.map +0 -1
  134. package/rollup.config.mjs +0 -210
  135. package/src/index.ts +0 -1
  136. package/src/mini.ts +0 -1
  137. package/src/react-client.ts +0 -3
  138. package/src/react-m.ts +0 -3
  139. package/src/react-mini.ts +0 -3
  140. package/src/react.ts +0 -3
  141. package/tsconfig.json +0 -25
  142. package/types/index.d.ts +0 -1
  143. package/types/mini.d.ts +0 -1
  144. package/types/react-client.d.ts +0 -1
  145. package/types/react-m.d.ts +0 -1
  146. package/types/react-mini.d.ts +0 -1
  147. package/types/react.d.ts +0 -1
  148. /package/dist/es/framer-motion/dist/es/render/html/utils/{transform.mjs → keys-transform.mjs} +0 -0
  149. /package/dist/es/{framer-motion → motion-dom}/dist/es/animation/generators/utils/calc-duration.mjs +0 -0
  150. /package/dist/es/{framer-motion → motion-dom}/dist/es/animation/generators/utils/is-generator.mjs +0 -0
  151. /package/dist/es/{framer-motion → motion-dom}/dist/es/animation/utils/get-value-transition.mjs +0 -0
  152. /package/dist/es/{framer-motion/dist/es/animation/animators → motion-dom/dist/es/animation}/waapi/utils/attach-timeline.mjs +0 -0
  153. /package/dist/es/{framer-motion → motion-dom}/dist/es/gestures/utils/is-node-or-child.mjs +0 -0
  154. /package/dist/es/{framer-motion/dist/es/events → motion-dom/dist/es/gestures}/utils/is-primary-pointer.mjs +0 -0
  155. /package/dist/es/{framer-motion/dist/es/easing → motion-dom/dist/es}/utils/is-bezier-definition.mjs +0 -0
  156. /package/dist/es/{framer-motion/dist/es/animation/animators/waapi/utils/supports-flags.mjs → motion-dom/dist/es/utils/supports/flags.mjs} +0 -0
  157. /package/dist/es/{framer-motion/dist/es/utils → motion-utils/dist/es}/errors.mjs +0 -0
package/dist/cjs/mini.js CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ /*#__NO_SIDE_EFFECTS__*/
6
+ const noop = (any) => any;
7
+
8
+ let invariant = noop;
9
+ if (process.env.NODE_ENV !== "production") {
10
+ invariant = (check, message) => {
11
+ if (!check) {
12
+ throw new Error(message);
13
+ }
14
+ };
15
+ }
16
+
17
+ /*#__NO_SIDE_EFFECTS__*/
5
18
  function memo(callback) {
6
19
  let result;
7
20
  return () => {
@@ -11,16 +24,46 @@ function memo(callback) {
11
24
  };
12
25
  }
13
26
 
27
+ /*
28
+ Progress within given range
29
+
30
+ Given a lower limit and an upper limit, we return the progress
31
+ (expressed as a number 0-1) represented by the given value, and
32
+ limit that progress to within 0-1.
33
+
34
+ @param [number]: Lower limit
35
+ @param [number]: Upper limit
36
+ @param [number]: Value to find progress within given range
37
+ @return [number]: Progress of value within range as expressed 0-1
38
+ */
39
+ /*#__NO_SIDE_EFFECTS__*/
40
+ const progress = (from, to, value) => {
41
+ const toFromDifference = to - from;
42
+ return toFromDifference === 0 ? 1 : (value - from) / toFromDifference;
43
+ };
44
+
45
+ /**
46
+ * Converts seconds to milliseconds
47
+ *
48
+ * @param seconds - Time in seconds.
49
+ * @return milliseconds - Converted time in milliseconds.
50
+ */
51
+ /*#__NO_SIDE_EFFECTS__*/
52
+ const secondsToMilliseconds = (seconds) => seconds * 1000;
53
+ /*#__NO_SIDE_EFFECTS__*/
54
+ const millisecondsToSeconds = (milliseconds) => milliseconds / 1000;
55
+
14
56
  const supportsScrollTimeline = memo(() => window.ScrollTimeline !== undefined);
15
57
 
16
- class GroupPlaybackControls {
58
+ class BaseGroupPlaybackControls {
17
59
  constructor(animations) {
18
60
  // Bound to accomodate common `return animation.stop` pattern
19
61
  this.stop = () => this.runAll("stop");
20
62
  this.animations = animations.filter(Boolean);
21
63
  }
22
- then(onResolve, onReject) {
23
- return Promise.all(this.animations).then(onResolve).catch(onReject);
64
+ get finished() {
65
+ // Support for new finished Promise and legacy thennable API
66
+ return Promise.all(this.animations.map((animation) => "finished" in animation ? animation.finished : animation));
24
67
  }
25
68
  /**
26
69
  * TODO: Filter out cancelled or stopped animations before returning
@@ -38,7 +81,7 @@ class GroupPlaybackControls {
38
81
  if (supportsScrollTimeline() && animation.attachTimeline) {
39
82
  return animation.attachTimeline(timeline);
40
83
  }
41
- else {
84
+ else if (typeof fallback === "function") {
42
85
  return fallback(animation);
43
86
  }
44
87
  });
@@ -91,52 +134,17 @@ class GroupPlaybackControls {
91
134
  }
92
135
  }
93
136
 
94
- const noop = (any) => any;
95
-
96
- let invariant = noop;
97
- if (process.env.NODE_ENV !== "production") {
98
- invariant = (check, message) => {
99
- if (!check) {
100
- throw new Error(message);
101
- }
102
- };
103
- }
104
-
105
- function resolveElements(elements, scope, selectorCache) {
106
- var _a;
107
- if (typeof elements === "string") {
108
- let root = document;
109
- if (scope) {
110
- invariant(Boolean(scope.current), "Scope provided, but no element detected.");
111
- root = scope.current;
112
- }
113
- if (selectorCache) {
114
- (_a = selectorCache[elements]) !== null && _a !== void 0 ? _a : (selectorCache[elements] = root.querySelectorAll(elements));
115
- elements = selectorCache[elements];
116
- }
117
- else {
118
- elements = root.querySelectorAll(elements);
119
- }
120
- }
121
- else if (elements instanceof Element) {
122
- elements = [elements];
123
- }
124
- /**
125
- * Return an empty array
126
- */
127
- return Array.from(elements || []);
128
- }
129
-
130
137
  /**
131
- * Converts seconds to milliseconds
132
- *
133
- * @param seconds - Time in seconds.
134
- * @return milliseconds - Converted time in milliseconds.
138
+ * TODO: This is a temporary class to support the legacy
139
+ * thennable API
135
140
  */
136
- const secondsToMilliseconds = (seconds) => seconds * 1000;
137
- const millisecondsToSeconds = (milliseconds) => milliseconds / 1000;
141
+ class GroupPlaybackControls extends BaseGroupPlaybackControls {
142
+ then(onResolve, onReject) {
143
+ return Promise.all(this.animations).then(onResolve).catch(onReject);
144
+ }
145
+ }
138
146
 
139
- function getValueTransition(transition, key) {
147
+ function getValueTransition$1(transition, key) {
140
148
  return transition
141
149
  ? transition[key] ||
142
150
  transition["default"] ||
@@ -144,36 +152,126 @@ function getValueTransition(transition, key) {
144
152
  : undefined;
145
153
  }
146
154
 
147
- const isBezierDefinition = (easing) => Array.isArray(easing) && typeof easing[0] === "number";
155
+ /**
156
+ * Implement a practical max duration for keyframe generation
157
+ * to prevent infinite loops
158
+ */
159
+ const maxGeneratorDuration = 20000;
160
+ function calcGeneratorDuration(generator) {
161
+ let duration = 0;
162
+ const timeStep = 50;
163
+ let state = generator.next(duration);
164
+ while (!state.done && duration < maxGeneratorDuration) {
165
+ duration += timeStep;
166
+ state = generator.next(duration);
167
+ }
168
+ return duration >= maxGeneratorDuration ? Infinity : duration;
169
+ }
148
170
 
149
- /*
150
- Progress within given range
171
+ /**
172
+ * Create a progress => progress easing function from a generator.
173
+ */
174
+ function createGeneratorEasing(options, scale = 100, createGenerator) {
175
+ const generator = createGenerator({ ...options, keyframes: [0, scale] });
176
+ const duration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
177
+ return {
178
+ type: "keyframes",
179
+ ease: (progress) => {
180
+ return generator.next(duration * progress).value / scale;
181
+ },
182
+ duration: millisecondsToSeconds(duration),
183
+ };
184
+ }
151
185
 
152
- Given a lower limit and an upper limit, we return the progress
153
- (expressed as a number 0-1) represented by the given value, and
154
- limit that progress to within 0-1.
186
+ function isGenerator(type) {
187
+ return typeof type === "function";
188
+ }
155
189
 
156
- @param [number]: Lower limit
157
- @param [number]: Upper limit
158
- @param [number]: Value to find progress within given range
159
- @return [number]: Progress of value within range as expressed 0-1
160
- */
161
- const progress = (from, to, value) => {
162
- const toFromDifference = to - from;
163
- return toFromDifference === 0 ? 1 : (value - from) / toFromDifference;
164
- };
190
+ function attachTimeline(animation, timeline) {
191
+ animation.timeline = timeline;
192
+ animation.onfinish = null;
193
+ }
165
194
 
166
- // Create a linear easing point for every 10 ms
167
- const resolution = 10;
168
- const generateLinearEasing = (easing, duration // as milliseconds
169
- ) => {
170
- let points = "";
171
- const numPoints = Math.max(Math.round(duration / resolution), 2);
172
- for (let i = 0; i < numPoints; i++) {
173
- points += easing(progress(0, numPoints - 1, i)) + ", ";
195
+ class NativeAnimationControls {
196
+ constructor(animation) {
197
+ this.animation = animation;
174
198
  }
175
- return `linear(${points.substring(0, points.length - 2)})`;
176
- };
199
+ get duration() {
200
+ var _a, _b, _c;
201
+ const durationInMs = ((_b = (_a = this.animation) === null || _a === void 0 ? void 0 : _a.effect) === null || _b === void 0 ? void 0 : _b.getComputedTiming().duration) ||
202
+ ((_c = this.options) === null || _c === void 0 ? void 0 : _c.duration) ||
203
+ 300;
204
+ return millisecondsToSeconds(Number(durationInMs));
205
+ }
206
+ get time() {
207
+ var _a;
208
+ if (this.animation) {
209
+ return millisecondsToSeconds(((_a = this.animation) === null || _a === void 0 ? void 0 : _a.currentTime) || 0);
210
+ }
211
+ return 0;
212
+ }
213
+ set time(newTime) {
214
+ if (this.animation) {
215
+ this.animation.currentTime = secondsToMilliseconds(newTime);
216
+ }
217
+ }
218
+ get speed() {
219
+ return this.animation ? this.animation.playbackRate : 1;
220
+ }
221
+ set speed(newSpeed) {
222
+ if (this.animation) {
223
+ this.animation.playbackRate = newSpeed;
224
+ }
225
+ }
226
+ get state() {
227
+ return this.animation ? this.animation.playState : "finished";
228
+ }
229
+ get startTime() {
230
+ return this.animation ? this.animation.startTime : null;
231
+ }
232
+ get finished() {
233
+ return this.animation ? this.animation.finished : Promise.resolve();
234
+ }
235
+ play() {
236
+ this.animation && this.animation.play();
237
+ }
238
+ pause() {
239
+ this.animation && this.animation.pause();
240
+ }
241
+ stop() {
242
+ if (!this.animation ||
243
+ this.state === "idle" ||
244
+ this.state === "finished") {
245
+ return;
246
+ }
247
+ if (this.animation.commitStyles) {
248
+ this.animation.commitStyles();
249
+ }
250
+ this.cancel();
251
+ }
252
+ flatten() {
253
+ var _a;
254
+ if (!this.animation)
255
+ return;
256
+ (_a = this.animation.effect) === null || _a === void 0 ? void 0 : _a.updateTiming({ easing: "linear" });
257
+ }
258
+ attachTimeline(timeline) {
259
+ if (this.animation)
260
+ attachTimeline(this.animation, timeline);
261
+ return noop;
262
+ }
263
+ complete() {
264
+ this.animation && this.animation.finish();
265
+ }
266
+ cancel() {
267
+ try {
268
+ this.animation && this.animation.cancel();
269
+ }
270
+ catch (e) { }
271
+ }
272
+ }
273
+
274
+ const isBezierDefinition = (easing) => Array.isArray(easing) && typeof easing[0] === "number";
177
275
 
178
276
  /**
179
277
  * Add the ability for test suites to manually set support flags
@@ -200,6 +298,17 @@ const supportsLinearEasing = /*@__PURE__*/ memoSupports(() => {
200
298
  return true;
201
299
  }, "linearEasing");
202
300
 
301
+ const generateLinearEasing = (easing, duration, // as milliseconds
302
+ resolution = 10 // as milliseconds
303
+ ) => {
304
+ let points = "";
305
+ const numPoints = Math.max(Math.round(duration / resolution), 2);
306
+ for (let i = 0; i < numPoints; i++) {
307
+ points += easing(progress(0, numPoints - 1, i)) + ", ";
308
+ }
309
+ return `linear(${points.substring(0, points.length - 2)})`;
310
+ };
311
+
203
312
  const cubicBezierAsString = ([a, b, c, d]) => `cubic-bezier(${a}, ${b}, ${c}, ${d})`;
204
313
  const supportedWaapiEasing = {
205
314
  linear: "linear",
@@ -231,6 +340,420 @@ function mapEasingToNativeEasing(easing, duration) {
231
340
  }
232
341
  }
233
342
 
343
+ function resolveElements(elementOrSelector, scope, selectorCache) {
344
+ var _a;
345
+ if (elementOrSelector instanceof Element) {
346
+ return [elementOrSelector];
347
+ }
348
+ else if (typeof elementOrSelector === "string") {
349
+ let root = document;
350
+ if (scope) {
351
+ // TODO: Refactor to utils package
352
+ // invariant(
353
+ // Boolean(scope.current),
354
+ // "Scope provided, but no element detected."
355
+ // )
356
+ root = scope.current;
357
+ }
358
+ const elements = (_a = selectorCache === null || selectorCache === void 0 ? void 0 : selectorCache[elementOrSelector]) !== null && _a !== void 0 ? _a : root.querySelectorAll(elementOrSelector);
359
+ return elements ? Array.from(elements) : [];
360
+ }
361
+ return Array.from(elementOrSelector);
362
+ }
363
+
364
+ const wrap = (min, max, v) => {
365
+ const rangeSize = max - min;
366
+ return ((((v - min) % rangeSize) + rangeSize) % rangeSize) + min;
367
+ };
368
+
369
+ const isEasingArray = (ease) => {
370
+ return Array.isArray(ease) && typeof ease[0] !== "number";
371
+ };
372
+
373
+ function getEasingForSegment(easing, i) {
374
+ return isEasingArray(easing) ? easing[wrap(0, easing.length, i)] : easing;
375
+ }
376
+
377
+ /*
378
+ Value in range from progress
379
+
380
+ Given a lower limit and an upper limit, we return the value within
381
+ that range as expressed by progress (usually a number from 0 to 1)
382
+
383
+ So progress = 0.5 would change
384
+
385
+ from -------- to
386
+
387
+ to
388
+
389
+ from ---- to
390
+
391
+ E.g. from = 10, to = 20, progress = 0.5 => 15
392
+
393
+ @param [number]: Lower limit of range
394
+ @param [number]: Upper limit of range
395
+ @param [number]: The progress between lower and upper limits expressed 0-1
396
+ @return [number]: Value as calculated from progress within range (not limited within range)
397
+ */
398
+ const mixNumber = (from, to, progress) => {
399
+ return from + (to - from) * progress;
400
+ };
401
+
402
+ function fillOffset(offset, remaining) {
403
+ const min = offset[offset.length - 1];
404
+ for (let i = 1; i <= remaining; i++) {
405
+ const offsetProgress = progress(0, remaining, i);
406
+ offset.push(mixNumber(min, 1, offsetProgress));
407
+ }
408
+ }
409
+
410
+ function defaultOffset(arr) {
411
+ const offset = [0];
412
+ fillOffset(offset, arr.length - 1);
413
+ return offset;
414
+ }
415
+
416
+ const isMotionValue = (value) => Boolean(value && value.getVelocity);
417
+
418
+ function isDOMKeyframes(keyframes) {
419
+ return typeof keyframes === "object" && !Array.isArray(keyframes);
420
+ }
421
+
422
+ function resolveSubjects(subject, keyframes, scope, selectorCache) {
423
+ if (typeof subject === "string" && isDOMKeyframes(keyframes)) {
424
+ return resolveElements(subject, scope, selectorCache);
425
+ }
426
+ else if (subject instanceof NodeList) {
427
+ return Array.from(subject);
428
+ }
429
+ else if (Array.isArray(subject)) {
430
+ return subject;
431
+ }
432
+ else {
433
+ return [subject];
434
+ }
435
+ }
436
+
437
+ function calculateRepeatDuration(duration, repeat, _repeatDelay) {
438
+ return duration * (repeat + 1);
439
+ }
440
+
441
+ /**
442
+ * Given a absolute or relative time definition and current/prev time state of the sequence,
443
+ * calculate an absolute time for the next keyframes.
444
+ */
445
+ function calcNextTime(current, next, prev, labels) {
446
+ var _a;
447
+ if (typeof next === "number") {
448
+ return next;
449
+ }
450
+ else if (next.startsWith("-") || next.startsWith("+")) {
451
+ return Math.max(0, current + parseFloat(next));
452
+ }
453
+ else if (next === "<") {
454
+ return prev;
455
+ }
456
+ else {
457
+ return (_a = labels.get(next)) !== null && _a !== void 0 ? _a : current;
458
+ }
459
+ }
460
+
461
+ function removeItem(arr, item) {
462
+ const index = arr.indexOf(item);
463
+ if (index > -1)
464
+ arr.splice(index, 1);
465
+ }
466
+
467
+ function eraseKeyframes(sequence, startTime, endTime) {
468
+ for (let i = 0; i < sequence.length; i++) {
469
+ const keyframe = sequence[i];
470
+ if (keyframe.at > startTime && keyframe.at < endTime) {
471
+ removeItem(sequence, keyframe);
472
+ // If we remove this item we have to push the pointer back one
473
+ i--;
474
+ }
475
+ }
476
+ }
477
+ function addKeyframes(sequence, keyframes, easing, offset, startTime, endTime) {
478
+ /**
479
+ * Erase every existing value between currentTime and targetTime,
480
+ * this will essentially splice this timeline into any currently
481
+ * defined ones.
482
+ */
483
+ eraseKeyframes(sequence, startTime, endTime);
484
+ for (let i = 0; i < keyframes.length; i++) {
485
+ sequence.push({
486
+ value: keyframes[i],
487
+ at: mixNumber(startTime, endTime, offset[i]),
488
+ easing: getEasingForSegment(easing, i),
489
+ });
490
+ }
491
+ }
492
+
493
+ /**
494
+ * Take an array of times that represent repeated keyframes. For instance
495
+ * if we have original times of [0, 0.5, 1] then our repeated times will
496
+ * be [0, 0.5, 1, 1, 1.5, 2]. Loop over the times and scale them back
497
+ * down to a 0-1 scale.
498
+ */
499
+ function normalizeTimes(times, repeat) {
500
+ for (let i = 0; i < times.length; i++) {
501
+ times[i] = times[i] / (repeat + 1);
502
+ }
503
+ }
504
+
505
+ function compareByTime(a, b) {
506
+ if (a.at === b.at) {
507
+ if (a.value === null)
508
+ return 1;
509
+ if (b.value === null)
510
+ return -1;
511
+ return 0;
512
+ }
513
+ else {
514
+ return a.at - b.at;
515
+ }
516
+ }
517
+
518
+ const defaultSegmentEasing = "easeInOut";
519
+ const MAX_REPEAT = 20;
520
+ function createAnimationsFromSequence(sequence, { defaultTransition = {}, ...sequenceTransition } = {}, scope, generators) {
521
+ const defaultDuration = defaultTransition.duration || 0.3;
522
+ const animationDefinitions = new Map();
523
+ const sequences = new Map();
524
+ const elementCache = {};
525
+ const timeLabels = new Map();
526
+ let prevTime = 0;
527
+ let currentTime = 0;
528
+ let totalDuration = 0;
529
+ /**
530
+ * Build the timeline by mapping over the sequence array and converting
531
+ * the definitions into keyframes and offsets with absolute time values.
532
+ * These will later get converted into relative offsets in a second pass.
533
+ */
534
+ for (let i = 0; i < sequence.length; i++) {
535
+ const segment = sequence[i];
536
+ /**
537
+ * If this is a timeline label, mark it and skip the rest of this iteration.
538
+ */
539
+ if (typeof segment === "string") {
540
+ timeLabels.set(segment, currentTime);
541
+ continue;
542
+ }
543
+ else if (!Array.isArray(segment)) {
544
+ timeLabels.set(segment.name, calcNextTime(currentTime, segment.at, prevTime, timeLabels));
545
+ continue;
546
+ }
547
+ let [subject, keyframes, transition = {}] = segment;
548
+ /**
549
+ * If a relative or absolute time value has been specified we need to resolve
550
+ * it in relation to the currentTime.
551
+ */
552
+ if (transition.at !== undefined) {
553
+ currentTime = calcNextTime(currentTime, transition.at, prevTime, timeLabels);
554
+ }
555
+ /**
556
+ * Keep track of the maximum duration in this definition. This will be
557
+ * applied to currentTime once the definition has been parsed.
558
+ */
559
+ let maxDuration = 0;
560
+ const resolveValueSequence = (valueKeyframes, valueTransition, valueSequence, elementIndex = 0, numSubjects = 0) => {
561
+ const valueKeyframesAsList = keyframesAsList(valueKeyframes);
562
+ const { delay = 0, times = defaultOffset(valueKeyframesAsList), type = "keyframes", repeat, repeatType, repeatDelay = 0, ...remainingTransition } = valueTransition;
563
+ let { ease = defaultTransition.ease || "easeOut", duration } = valueTransition;
564
+ /**
565
+ * Resolve stagger() if defined.
566
+ */
567
+ const calculatedDelay = typeof delay === "function"
568
+ ? delay(elementIndex, numSubjects)
569
+ : delay;
570
+ /**
571
+ * If this animation should and can use a spring, generate a spring easing function.
572
+ */
573
+ const numKeyframes = valueKeyframesAsList.length;
574
+ const createGenerator = isGenerator(type)
575
+ ? type
576
+ : generators === null || generators === void 0 ? void 0 : generators[type];
577
+ if (numKeyframes <= 2 && createGenerator) {
578
+ /**
579
+ * As we're creating an easing function from a spring,
580
+ * ideally we want to generate it using the real distance
581
+ * between the two keyframes. However this isn't always
582
+ * possible - in these situations we use 0-100.
583
+ */
584
+ let absoluteDelta = 100;
585
+ if (numKeyframes === 2 &&
586
+ isNumberKeyframesArray(valueKeyframesAsList)) {
587
+ const delta = valueKeyframesAsList[1] - valueKeyframesAsList[0];
588
+ absoluteDelta = Math.abs(delta);
589
+ }
590
+ const springTransition = { ...remainingTransition };
591
+ if (duration !== undefined) {
592
+ springTransition.duration = secondsToMilliseconds(duration);
593
+ }
594
+ const springEasing = createGeneratorEasing(springTransition, absoluteDelta, createGenerator);
595
+ ease = springEasing.ease;
596
+ duration = springEasing.duration;
597
+ }
598
+ duration !== null && duration !== void 0 ? duration : (duration = defaultDuration);
599
+ const startTime = currentTime + calculatedDelay;
600
+ /**
601
+ * If there's only one time offset of 0, fill in a second with length 1
602
+ */
603
+ if (times.length === 1 && times[0] === 0) {
604
+ times[1] = 1;
605
+ }
606
+ /**
607
+ * Fill out if offset if fewer offsets than keyframes
608
+ */
609
+ const remainder = times.length - valueKeyframesAsList.length;
610
+ remainder > 0 && fillOffset(times, remainder);
611
+ /**
612
+ * If only one value has been set, ie [1], push a null to the start of
613
+ * the keyframe array. This will let us mark a keyframe at this point
614
+ * that will later be hydrated with the previous value.
615
+ */
616
+ valueKeyframesAsList.length === 1 &&
617
+ valueKeyframesAsList.unshift(null);
618
+ /**
619
+ * Handle repeat options
620
+ */
621
+ if (repeat) {
622
+ invariant(repeat < MAX_REPEAT, "Repeat count too high, must be less than 20");
623
+ duration = calculateRepeatDuration(duration, repeat);
624
+ const originalKeyframes = [...valueKeyframesAsList];
625
+ const originalTimes = [...times];
626
+ ease = Array.isArray(ease) ? [...ease] : [ease];
627
+ const originalEase = [...ease];
628
+ for (let repeatIndex = 0; repeatIndex < repeat; repeatIndex++) {
629
+ valueKeyframesAsList.push(...originalKeyframes);
630
+ for (let keyframeIndex = 0; keyframeIndex < originalKeyframes.length; keyframeIndex++) {
631
+ times.push(originalTimes[keyframeIndex] + (repeatIndex + 1));
632
+ ease.push(keyframeIndex === 0
633
+ ? "linear"
634
+ : getEasingForSegment(originalEase, keyframeIndex - 1));
635
+ }
636
+ }
637
+ normalizeTimes(times, repeat);
638
+ }
639
+ const targetTime = startTime + duration;
640
+ /**
641
+ * Add keyframes, mapping offsets to absolute time.
642
+ */
643
+ addKeyframes(valueSequence, valueKeyframesAsList, ease, times, startTime, targetTime);
644
+ maxDuration = Math.max(calculatedDelay + duration, maxDuration);
645
+ totalDuration = Math.max(targetTime, totalDuration);
646
+ };
647
+ if (isMotionValue(subject)) {
648
+ const subjectSequence = getSubjectSequence(subject, sequences);
649
+ resolveValueSequence(keyframes, transition, getValueSequence("default", subjectSequence));
650
+ }
651
+ else {
652
+ const subjects = resolveSubjects(subject, keyframes, scope, elementCache);
653
+ const numSubjects = subjects.length;
654
+ /**
655
+ * For every element in this segment, process the defined values.
656
+ */
657
+ for (let subjectIndex = 0; subjectIndex < numSubjects; subjectIndex++) {
658
+ /**
659
+ * Cast necessary, but we know these are of this type
660
+ */
661
+ keyframes = keyframes;
662
+ transition = transition;
663
+ const thisSubject = subjects[subjectIndex];
664
+ const subjectSequence = getSubjectSequence(thisSubject, sequences);
665
+ for (const key in keyframes) {
666
+ resolveValueSequence(keyframes[key], getValueTransition(transition, key), getValueSequence(key, subjectSequence), subjectIndex, numSubjects);
667
+ }
668
+ }
669
+ }
670
+ prevTime = currentTime;
671
+ currentTime += maxDuration;
672
+ }
673
+ /**
674
+ * For every element and value combination create a new animation.
675
+ */
676
+ sequences.forEach((valueSequences, element) => {
677
+ for (const key in valueSequences) {
678
+ const valueSequence = valueSequences[key];
679
+ /**
680
+ * Arrange all the keyframes in ascending time order.
681
+ */
682
+ valueSequence.sort(compareByTime);
683
+ const keyframes = [];
684
+ const valueOffset = [];
685
+ const valueEasing = [];
686
+ /**
687
+ * For each keyframe, translate absolute times into
688
+ * relative offsets based on the total duration of the timeline.
689
+ */
690
+ for (let i = 0; i < valueSequence.length; i++) {
691
+ const { at, value, easing } = valueSequence[i];
692
+ keyframes.push(value);
693
+ valueOffset.push(progress(0, totalDuration, at));
694
+ valueEasing.push(easing || "easeOut");
695
+ }
696
+ /**
697
+ * If the first keyframe doesn't land on offset: 0
698
+ * provide one by duplicating the initial keyframe. This ensures
699
+ * it snaps to the first keyframe when the animation starts.
700
+ */
701
+ if (valueOffset[0] !== 0) {
702
+ valueOffset.unshift(0);
703
+ keyframes.unshift(keyframes[0]);
704
+ valueEasing.unshift(defaultSegmentEasing);
705
+ }
706
+ /**
707
+ * If the last keyframe doesn't land on offset: 1
708
+ * provide one with a null wildcard value. This will ensure it
709
+ * stays static until the end of the animation.
710
+ */
711
+ if (valueOffset[valueOffset.length - 1] !== 1) {
712
+ valueOffset.push(1);
713
+ keyframes.push(null);
714
+ }
715
+ if (!animationDefinitions.has(element)) {
716
+ animationDefinitions.set(element, {
717
+ keyframes: {},
718
+ transition: {},
719
+ });
720
+ }
721
+ const definition = animationDefinitions.get(element);
722
+ definition.keyframes[key] = keyframes;
723
+ definition.transition[key] = {
724
+ ...defaultTransition,
725
+ duration: totalDuration,
726
+ ease: valueEasing,
727
+ times: valueOffset,
728
+ ...sequenceTransition,
729
+ };
730
+ }
731
+ });
732
+ return animationDefinitions;
733
+ }
734
+ function getSubjectSequence(subject, sequences) {
735
+ !sequences.has(subject) && sequences.set(subject, {});
736
+ return sequences.get(subject);
737
+ }
738
+ function getValueSequence(name, sequences) {
739
+ if (!sequences[name])
740
+ sequences[name] = [];
741
+ return sequences[name];
742
+ }
743
+ function keyframesAsList(keyframes) {
744
+ return Array.isArray(keyframes) ? keyframes : [keyframes];
745
+ }
746
+ function getValueTransition(transition, key) {
747
+ return transition && transition[key]
748
+ ? {
749
+ ...transition,
750
+ ...transition[key],
751
+ }
752
+ : { ...transition };
753
+ }
754
+ const isNumber = (keyframe) => typeof keyframe === "number";
755
+ const isNumberKeyframesArray = (keyframes) => keyframes.every(isNumber);
756
+
234
757
  function startWaapiAnimation(element, valueName, keyframes, { delay = 0, duration = 300, repeat = 0, repeatType = "loop", ease = "easeInOut", times, } = {}) {
235
758
  const keyframeOptions = { [valueName]: keyframes };
236
759
  if (times)
@@ -251,35 +774,6 @@ function startWaapiAnimation(element, valueName, keyframes, { delay = 0, duratio
251
774
  });
252
775
  }
253
776
 
254
- /**
255
- * Implement a practical max duration for keyframe generation
256
- * to prevent infinite loops
257
- */
258
- const maxGeneratorDuration = 20000;
259
- function calcGeneratorDuration(generator) {
260
- let duration = 0;
261
- const timeStep = 50;
262
- let state = generator.next(duration);
263
- while (!state.done && duration < maxGeneratorDuration) {
264
- duration += timeStep;
265
- state = generator.next(duration);
266
- }
267
- return duration >= maxGeneratorDuration ? Infinity : duration;
268
- }
269
-
270
- /**
271
- * Create a progress => progress easing function from a generator.
272
- */
273
- function createGeneratorEasing(options, scale = 100, createGenerator) {
274
- const generator = createGenerator({ ...options, keyframes: [0, scale] });
275
- const duration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
276
- return {
277
- type: "keyframes",
278
- ease: (progress) => generator.next(duration * progress).value / scale,
279
- duration: millisecondsToSeconds(duration),
280
- };
281
- }
282
-
283
777
  const createUnitType = (unit) => ({
284
778
  test: (v) => typeof v === "string" && v.endsWith(unit) && v.split(" ").length === 1,
285
779
  parse: parseFloat,
@@ -325,15 +819,6 @@ const browserNumberValueTypes = {
325
819
  backgroundPositionY: px,
326
820
  };
327
821
 
328
- function isGenerator(type) {
329
- return typeof type === "function";
330
- }
331
-
332
- function attachTimeline(animation, timeline) {
333
- animation.timeline = timeline;
334
- animation.onfinish = null;
335
- }
336
-
337
822
  const isNotNull = (value) => value !== null;
338
823
  function getFinalKeyframe(keyframes, { repeat, repeatType = "loop" }, finalKeyframe) {
339
824
  const resolvedKeyframes = keyframes.filter(isNotNull);
@@ -385,12 +870,9 @@ function getElementAnimationState(element) {
385
870
  state.set(element, animationState);
386
871
  return state.get(element);
387
872
  }
388
- class NativeAnimation {
873
+ class NativeAnimation extends NativeAnimationControls {
389
874
  constructor(element, valueName, valueKeyframes, options) {
390
875
  const isCSSVar = valueName.startsWith("--");
391
- this.setValue = isCSSVar ? setCSSVar : setStyle;
392
- this.options = options;
393
- this.updateFinishedPromise();
394
876
  invariant(typeof options.type !== "string", `animateMini doesn't support "type" as a string. Did you mean to import { spring } from "framer-motion"?`);
395
877
  const existingAnimation = getElementAnimationState(element).get(valueName);
396
878
  existingAnimation && existingAnimation.stop();
@@ -403,6 +885,7 @@ class NativeAnimation {
403
885
  valueKeyframes = [valueKeyframes];
404
886
  }
405
887
  hydrateKeyframes(valueName, valueKeyframes, readInitialKeyframe);
888
+ // TODO: Replace this with toString()?
406
889
  if (isGenerator(options.type)) {
407
890
  const generatorOptions = createGeneratorEasing(options, 100, options.type);
408
891
  options.ease = supportsLinearEasing()
@@ -414,92 +897,35 @@ class NativeAnimation {
414
897
  else {
415
898
  options.ease = options.ease || defaultEasing;
416
899
  }
417
- this.removeAnimation = () => { var _a; return (_a = state.get(element)) === null || _a === void 0 ? void 0 : _a.delete(valueName); };
418
900
  const onFinish = () => {
419
- this.setValue(element, valueName, getFinalKeyframe(valueKeyframes, this.options));
901
+ this.setValue(element, valueName, getFinalKeyframe(valueKeyframes, options));
420
902
  this.cancel();
421
903
  this.resolveFinishedPromise();
422
904
  };
905
+ const init = () => {
906
+ this.setValue = isCSSVar ? setCSSVar : setStyle;
907
+ this.options = options;
908
+ this.updateFinishedPromise();
909
+ this.removeAnimation = () => {
910
+ const elementState = state.get(element);
911
+ elementState && elementState.delete(valueName);
912
+ };
913
+ };
423
914
  if (!supportsWaapi()) {
915
+ super();
916
+ init();
424
917
  onFinish();
425
918
  }
426
919
  else {
427
- this.animation = startWaapiAnimation(element, valueName, valueKeyframes, options);
920
+ super(startWaapiAnimation(element, valueName, valueKeyframes, options));
921
+ init();
428
922
  if (options.autoplay === false) {
429
923
  this.animation.pause();
430
924
  }
431
925
  this.animation.onfinish = onFinish;
432
- if (this.pendingTimeline) {
433
- attachTimeline(this.animation, this.pendingTimeline);
434
- }
435
926
  getElementAnimationState(element).set(valueName, this);
436
927
  }
437
928
  }
438
- get duration() {
439
- return millisecondsToSeconds(this.options.duration || 300);
440
- }
441
- get time() {
442
- var _a;
443
- if (this.animation) {
444
- return millisecondsToSeconds(((_a = this.animation) === null || _a === void 0 ? void 0 : _a.currentTime) || 0);
445
- }
446
- return 0;
447
- }
448
- set time(newTime) {
449
- if (this.animation) {
450
- this.animation.currentTime = secondsToMilliseconds(newTime);
451
- }
452
- }
453
- get speed() {
454
- return this.animation ? this.animation.playbackRate : 1;
455
- }
456
- set speed(newSpeed) {
457
- if (this.animation) {
458
- this.animation.playbackRate = newSpeed;
459
- }
460
- }
461
- get state() {
462
- return this.animation ? this.animation.playState : "finished";
463
- }
464
- get startTime() {
465
- return this.animation ? this.animation.startTime : null;
466
- }
467
- flatten() {
468
- var _a;
469
- if (!this.animation)
470
- return;
471
- (_a = this.animation.effect) === null || _a === void 0 ? void 0 : _a.updateTiming({ easing: "linear" });
472
- }
473
- play() {
474
- if (this.state === "finished") {
475
- this.updateFinishedPromise();
476
- }
477
- this.animation && this.animation.play();
478
- }
479
- pause() {
480
- this.animation && this.animation.pause();
481
- }
482
- stop() {
483
- if (!this.animation ||
484
- this.state === "idle" ||
485
- this.state === "finished") {
486
- return;
487
- }
488
- if (this.animation.commitStyles) {
489
- this.animation.commitStyles();
490
- }
491
- this.cancel();
492
- }
493
- complete() {
494
- this.animation && this.animation.finish();
495
- }
496
- cancel() {
497
- this.removeAnimation();
498
- try {
499
- this.animation && this.animation.cancel();
500
- }
501
- catch (e) { }
502
- }
503
929
  /**
504
930
  * Allows the returned animation to be awaited or promise-chained. Currently
505
931
  * resolves when the animation finishes at all but in a future update could/should
@@ -513,14 +939,15 @@ class NativeAnimation {
513
939
  this.resolveFinishedPromise = resolve;
514
940
  });
515
941
  }
516
- attachTimeline(timeline) {
517
- if (!this.animation) {
518
- this.pendingTimeline = timeline;
519
- }
520
- else {
521
- attachTimeline(this.animation, timeline);
942
+ play() {
943
+ if (this.state === "finished") {
944
+ this.updateFinishedPromise();
522
945
  }
523
- return noop;
946
+ super.play();
947
+ }
948
+ cancel() {
949
+ this.removeAnimation();
950
+ super.cancel();
524
951
  }
525
952
  }
526
953
 
@@ -541,7 +968,7 @@ function animateElements(elementOrSelector, keyframes, options, scope) {
541
968
  for (const valueName in keyframes) {
542
969
  const valueKeyframes = keyframes[valueName];
543
970
  const valueOptions = {
544
- ...getValueTransition(elementTransition, valueName),
971
+ ...getValueTransition$1(elementTransition, valueName),
545
972
  };
546
973
  valueOptions.duration = valueOptions.duration
547
974
  ? secondsToMilliseconds(valueOptions.duration)
@@ -553,6 +980,14 @@ function animateElements(elementOrSelector, keyframes, options, scope) {
553
980
  return animations;
554
981
  }
555
982
 
983
+ function animateSequence(definition, options) {
984
+ const animations = [];
985
+ createAnimationsFromSequence(definition, options).forEach(({ keyframes, transition }, element) => {
986
+ animations.push(...animateElements(element, keyframes, transition));
987
+ });
988
+ return new GroupPlaybackControls(animations);
989
+ }
990
+
556
991
  const createScopedWaapiAnimate = (scope) => {
557
992
  function scopedAnimate(elementOrSelector, keyframes, options) {
558
993
  return new GroupPlaybackControls(animateElements(elementOrSelector, keyframes, options, scope));
@@ -562,3 +997,4 @@ const createScopedWaapiAnimate = (scope) => {
562
997
  const animateMini = /*@__PURE__*/ createScopedWaapiAnimate();
563
998
 
564
999
  exports.animate = animateMini;
1000
+ exports.animateSequence = animateSequence;