UNPKG

301 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) :
3 typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) :
4 (global = global || self, factory(global.Motion = {}, global.React));
5}(this, function (exports, React) { 'use strict';
6
7 /*! *****************************************************************************
8 Copyright (c) Microsoft Corporation. All rights reserved.
9 Licensed under the Apache License, Version 2.0 (the "License"); you may not use
10 this file except in compliance with the License. You may obtain a copy of the
11 License at http://www.apache.org/licenses/LICENSE-2.0
12
13 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
15 WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
16 MERCHANTABLITY OR NON-INFRINGEMENT.
17
18 See the Apache Version 2.0 License for specific language governing permissions
19 and limitations under the License.
20 ***************************************************************************** */
21 /* global Reflect, Promise */
22
23 var extendStatics = function(d, b) {
24 extendStatics = Object.setPrototypeOf ||
25 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
26 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
27 return extendStatics(d, b);
28 };
29
30 function __extends(d, b) {
31 extendStatics(d, b);
32 function __() { this.constructor = d; }
33 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
34 }
35
36 var __assign = function() {
37 __assign = Object.assign || function __assign(t) {
38 for (var s, i = 1, n = arguments.length; i < n; i++) {
39 s = arguments[i];
40 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
41 }
42 return t;
43 };
44 return __assign.apply(this, arguments);
45 };
46
47 function __rest(s, e) {
48 var t = {};
49 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
50 t[p] = s[p];
51 if (s != null && typeof Object.getOwnPropertySymbols === "function")
52 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
53 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
54 t[p[i]] = s[p[i]];
55 }
56 return t;
57 }
58
59 function __spreadArrays() {
60 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
61 for (var r = Array(s), k = 0, i = 0; i < il; i++)
62 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
63 r[k] = a[j];
64 return r;
65 }
66
67 var warning = function () { };
68 var invariant = function () { };
69 {
70 warning = function (check, message) {
71 if (!check && typeof console !== 'undefined') {
72 console.warn(message);
73 }
74 };
75 invariant = function (check, message) {
76 if (!check) {
77 throw new Error(message);
78 }
79 };
80 }
81
82 var prevTime = 0;
83 var onNextFrame = typeof window !== 'undefined' && window.requestAnimationFrame !== undefined
84 ? function (callback) { return window.requestAnimationFrame(callback); }
85 : function (callback) {
86 var timestamp = Date.now();
87 var timeToCall = Math.max(0, 16.7 - (timestamp - prevTime));
88 prevTime = timestamp + timeToCall;
89 setTimeout(function () { return callback(prevTime); }, timeToCall);
90 };
91
92 var createStep = (function (setRunNextFrame) {
93 var processToRun = [];
94 var processToRunNextFrame = [];
95 var numThisFrame = 0;
96 var isProcessing = false;
97 var i = 0;
98 var cancelled = new WeakSet();
99 var toKeepAlive = new WeakSet();
100 var renderStep = {
101 cancel: function (process) {
102 var indexOfCallback = processToRunNextFrame.indexOf(process);
103 cancelled.add(process);
104 if (indexOfCallback !== -1) {
105 processToRunNextFrame.splice(indexOfCallback, 1);
106 }
107 },
108 process: function (frame) {
109 var _a;
110 isProcessing = true;
111 _a = [
112 processToRunNextFrame,
113 processToRun
114 ], processToRun = _a[0], processToRunNextFrame = _a[1];
115 processToRunNextFrame.length = 0;
116 numThisFrame = processToRun.length;
117 if (numThisFrame) {
118 var process_1;
119 for (i = 0; i < numThisFrame; i++) {
120 process_1 = processToRun[i];
121 process_1(frame);
122 if (toKeepAlive.has(process_1) === true && !cancelled.has(process_1)) {
123 renderStep.schedule(process_1);
124 setRunNextFrame(true);
125 }
126 }
127 }
128 isProcessing = false;
129 },
130 schedule: function (process, keepAlive, immediate) {
131 if (keepAlive === void 0) { keepAlive = false; }
132 if (immediate === void 0) { immediate = false; }
133 invariant(typeof process === 'function', 'Argument must be a function');
134 var addToCurrentBuffer = immediate && isProcessing;
135 var buffer = addToCurrentBuffer ? processToRun : processToRunNextFrame;
136 cancelled.delete(process);
137 if (keepAlive)
138 toKeepAlive.add(process);
139 if (buffer.indexOf(process) === -1) {
140 buffer.push(process);
141 if (addToCurrentBuffer)
142 numThisFrame = processToRun.length;
143 }
144 }
145 };
146 return renderStep;
147 });
148
149 var StepId;
150 (function (StepId) {
151 StepId["Read"] = "read";
152 StepId["Update"] = "update";
153 StepId["Render"] = "render";
154 StepId["PostRender"] = "postRender";
155 StepId["FixedUpdate"] = "fixedUpdate";
156 })(StepId || (StepId = {}));
157
158 var maxElapsed = 40;
159 var defaultElapsed = (1 / 60) * 1000;
160 var useDefaultElapsed = true;
161 var willRunNextFrame = false;
162 var isProcessing = false;
163 var frame = {
164 delta: 0,
165 timestamp: 0
166 };
167 var stepsOrder = [
168 StepId.Read,
169 StepId.Update,
170 StepId.Render,
171 StepId.PostRender
172 ];
173 var setWillRunNextFrame = function (willRun) { return (willRunNextFrame = willRun); };
174 var _a = stepsOrder.reduce(function (acc, key) {
175 var step = createStep(setWillRunNextFrame);
176 acc.sync[key] = function (process, keepAlive, immediate) {
177 if (keepAlive === void 0) { keepAlive = false; }
178 if (immediate === void 0) { immediate = false; }
179 if (!willRunNextFrame)
180 startLoop();
181 step.schedule(process, keepAlive, immediate);
182 return process;
183 };
184 acc.cancelSync[key] = function (process) { return step.cancel(process); };
185 acc.steps[key] = step;
186 return acc;
187 }, {
188 steps: {},
189 sync: {},
190 cancelSync: {}
191 }), steps = _a.steps, sync = _a.sync, cancelSync = _a.cancelSync;
192 var processStep = function (stepId) { return steps[stepId].process(frame); };
193 var processFrame = function (timestamp) {
194 willRunNextFrame = false;
195 frame.delta = useDefaultElapsed
196 ? defaultElapsed
197 : Math.max(Math.min(timestamp - frame.timestamp, maxElapsed), 1);
198 if (!useDefaultElapsed)
199 defaultElapsed = frame.delta;
200 frame.timestamp = timestamp;
201 isProcessing = true;
202 stepsOrder.forEach(processStep);
203 isProcessing = false;
204 if (willRunNextFrame) {
205 useDefaultElapsed = false;
206 onNextFrame(processFrame);
207 }
208 };
209 var startLoop = function () {
210 willRunNextFrame = true;
211 useDefaultElapsed = true;
212 if (!isProcessing)
213 onNextFrame(processFrame);
214 };
215 var getFrameData = function () { return frame; };
216
217 /*! *****************************************************************************
218 Copyright (c) Microsoft Corporation. All rights reserved.
219 Licensed under the Apache License, Version 2.0 (the "License"); you may not use
220 this file except in compliance with the License. You may obtain a copy of the
221 License at http://www.apache.org/licenses/LICENSE-2.0
222
223 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
224 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
225 WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
226 MERCHANTABLITY OR NON-INFRINGEMENT.
227
228 See the Apache Version 2.0 License for specific language governing permissions
229 and limitations under the License.
230 ***************************************************************************** */
231
232 var __assign$1 = function() {
233 __assign$1 = Object.assign || function __assign(t) {
234 for (var s, i = 1, n = arguments.length; i < n; i++) {
235 s = arguments[i];
236 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
237 }
238 return t;
239 };
240 return __assign$1.apply(this, arguments);
241 };
242
243 var clamp = function (min, max) { return function (v) {
244 return Math.max(Math.min(v, max), min);
245 }; };
246 var sanitize = function (v) { return (v % 1 ? Number(v.toFixed(5)) : v); };
247 var floatRegex = /(-)?(\d[\d\.]*)/g;
248 var colorRegex = /(#[0-9a-f]{6}|#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))/gi;
249 var singleColorRegex = /^(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))$/i;
250
251 var number = {
252 test: function (v) { return typeof v === 'number'; },
253 parse: parseFloat,
254 transform: function (v) { return v; }
255 };
256 var alpha = __assign$1({}, number, { transform: clamp(0, 1) });
257 var scale = __assign$1({}, number, { default: 1 });
258
259 var createUnitType = function (unit) { return ({
260 test: function (v) {
261 return typeof v === 'string' && v.endsWith(unit) && v.split(' ').length === 1;
262 },
263 parse: parseFloat,
264 transform: function (v) { return "" + v + unit; }
265 }); };
266 var degrees = createUnitType('deg');
267 var percent = createUnitType('%');
268 var px = createUnitType('px');
269 var vh = createUnitType('vh');
270 var vw = createUnitType('vw');
271 var progressPercentage = __assign$1({}, percent, { parse: function (v) { return percent.parse(v) / 100; }, transform: function (v) { return percent.transform(v * 100); } });
272
273 var getValueFromFunctionString = function (value) {
274 return value.substring(value.indexOf('(') + 1, value.lastIndexOf(')'));
275 };
276 var clampRgbUnit = clamp(0, 255);
277 var isRgba = function (v) { return v.red !== undefined; };
278 var isHsla = function (v) { return v.hue !== undefined; };
279 var splitColorValues = function (terms) {
280 return function (v) {
281 if (typeof v !== 'string')
282 return v;
283 var values = {};
284 var valuesArray = getValueFromFunctionString(v).split(/,\s*/);
285 for (var i = 0; i < 4; i++) {
286 values[terms[i]] =
287 valuesArray[i] !== undefined ? parseFloat(valuesArray[i]) : 1;
288 }
289 return values;
290 };
291 };
292 var rgbaTemplate = function (_a) {
293 var red = _a.red, green = _a.green, blue = _a.blue, _b = _a.alpha, alpha$$1 = _b === void 0 ? 1 : _b;
294 return "rgba(" + red + ", " + green + ", " + blue + ", " + alpha$$1 + ")";
295 };
296 var hslaTemplate = function (_a) {
297 var hue = _a.hue, saturation = _a.saturation, lightness = _a.lightness, _b = _a.alpha, alpha$$1 = _b === void 0 ? 1 : _b;
298 return "hsla(" + hue + ", " + saturation + ", " + lightness + ", " + alpha$$1 + ")";
299 };
300 var rgbUnit = __assign$1({}, number, { transform: function (v) { return Math.round(clampRgbUnit(v)); } });
301 function isColorString(color, colorType) {
302 return color.startsWith(colorType) && singleColorRegex.test(color);
303 }
304 var rgba = {
305 test: function (v) { return (typeof v === 'string' ? isColorString(v, 'rgb') : isRgba(v)); },
306 parse: splitColorValues(['red', 'green', 'blue', 'alpha']),
307 transform: function (_a) {
308 var red = _a.red, green = _a.green, blue = _a.blue, _b = _a.alpha, alpha$$1 = _b === void 0 ? 1 : _b;
309 return rgbaTemplate({
310 red: rgbUnit.transform(red),
311 green: rgbUnit.transform(green),
312 blue: rgbUnit.transform(blue),
313 alpha: sanitize(alpha.transform(alpha$$1))
314 });
315 }
316 };
317 var hsla = {
318 test: function (v) { return (typeof v === 'string' ? isColorString(v, 'hsl') : isHsla(v)); },
319 parse: splitColorValues(['hue', 'saturation', 'lightness', 'alpha']),
320 transform: function (_a) {
321 var hue = _a.hue, saturation = _a.saturation, lightness = _a.lightness, _b = _a.alpha, alpha$$1 = _b === void 0 ? 1 : _b;
322 return hslaTemplate({
323 hue: Math.round(hue),
324 saturation: percent.transform(sanitize(saturation)),
325 lightness: percent.transform(sanitize(lightness)),
326 alpha: sanitize(alpha.transform(alpha$$1))
327 });
328 }
329 };
330 var hex = __assign$1({}, rgba, { test: function (v) { return typeof v === 'string' && isColorString(v, '#'); }, parse: function (v) {
331 var r = '';
332 var g = '';
333 var b = '';
334 if (v.length > 4) {
335 r = v.substr(1, 2);
336 g = v.substr(3, 2);
337 b = v.substr(5, 2);
338 }
339 else {
340 r = v.substr(1, 1);
341 g = v.substr(2, 1);
342 b = v.substr(3, 1);
343 r += r;
344 g += g;
345 b += b;
346 }
347 return {
348 red: parseInt(r, 16),
349 green: parseInt(g, 16),
350 blue: parseInt(b, 16),
351 alpha: 1
352 };
353 } });
354 var color = {
355 test: function (v) {
356 return (typeof v === 'string' && singleColorRegex.test(v)) ||
357 isRgba(v) ||
358 isHsla(v);
359 },
360 parse: function (v) {
361 if (rgba.test(v)) {
362 return rgba.parse(v);
363 }
364 else if (hsla.test(v)) {
365 return hsla.parse(v);
366 }
367 else if (hex.test(v)) {
368 return hex.parse(v);
369 }
370 return v;
371 },
372 transform: function (v) {
373 if (isRgba(v)) {
374 return rgba.transform(v);
375 }
376 else if (isHsla(v)) {
377 return hsla.transform(v);
378 }
379 return v;
380 }
381 };
382
383 var COLOR_TOKEN = '${c}';
384 var NUMBER_TOKEN = '${n}';
385 var convertNumbersToZero = function (v) {
386 return typeof v === 'number' ? 0 : v;
387 };
388 var complex = {
389 test: function (v) {
390 if (typeof v !== 'string' || !isNaN(v))
391 return false;
392 var numValues = 0;
393 var foundNumbers = v.match(floatRegex);
394 var foundColors = v.match(colorRegex);
395 if (foundNumbers)
396 numValues += foundNumbers.length;
397 if (foundColors)
398 numValues += foundColors.length;
399 return numValues > 0;
400 },
401 parse: function (v) {
402 var input = v;
403 var parsed = [];
404 var foundColors = input.match(colorRegex);
405 if (foundColors) {
406 input = input.replace(colorRegex, COLOR_TOKEN);
407 parsed.push.apply(parsed, foundColors.map(color.parse));
408 }
409 var foundNumbers = input.match(floatRegex);
410 if (foundNumbers) {
411 parsed.push.apply(parsed, foundNumbers.map(number.parse));
412 }
413 return parsed;
414 },
415 createTransformer: function (prop) {
416 var template = prop;
417 var token = 0;
418 var foundColors = prop.match(colorRegex);
419 var numColors = foundColors ? foundColors.length : 0;
420 if (foundColors) {
421 for (var i = 0; i < numColors; i++) {
422 template = template.replace(foundColors[i], COLOR_TOKEN);
423 token++;
424 }
425 }
426 var foundNumbers = template.match(floatRegex);
427 var numNumbers = foundNumbers ? foundNumbers.length : 0;
428 if (foundNumbers) {
429 for (var i = 0; i < numNumbers; i++) {
430 template = template.replace(foundNumbers[i], NUMBER_TOKEN);
431 token++;
432 }
433 }
434 return function (v) {
435 var output = template;
436 for (var i = 0; i < token; i++) {
437 output = output.replace(i < numColors ? COLOR_TOKEN : NUMBER_TOKEN, i < numColors ? color.transform(v[i]) : sanitize(v[i]));
438 }
439 return output;
440 };
441 },
442 getAnimatableNone: function (target) {
443 var parsedTarget = complex.parse(target);
444 var targetTransformer = complex.createTransformer(target);
445 return targetTransformer(parsedTarget.map(convertNumbersToZero));
446 }
447 };
448
449 var DEFAULT_OVERSHOOT_STRENGTH = 1.525;
450 var reversed = function (easing) {
451 return function (p) {
452 return 1 - easing(1 - p);
453 };
454 };
455 var mirrored = function (easing) {
456 return function (p) {
457 return p <= 0.5 ? easing(2 * p) / 2 : (2 - easing(2 * (1 - p))) / 2;
458 };
459 };
460 var createReversedEasing = reversed;
461 var createMirroredEasing = mirrored;
462 var createExpoIn = function (power) {
463 return function (p) {
464 return Math.pow(p, power);
465 };
466 };
467 var createBackIn = function (power) {
468 return function (p) {
469 return p * p * ((power + 1) * p - power);
470 };
471 };
472 var createAnticipateEasing = function (power) {
473 var backEasing = createBackIn(power);
474 return function (p) {
475 return (p *= 2) < 1 ? 0.5 * backEasing(p) : 0.5 * (2 - Math.pow(2, -10 * (p - 1)));
476 };
477 };
478 var linear = function (p) {
479 return p;
480 };
481 var easeIn = /*#__PURE__*/createExpoIn(2);
482 var easeOut = /*#__PURE__*/reversed(easeIn);
483 var easeInOut = /*#__PURE__*/mirrored(easeIn);
484 var circIn = function (p) {
485 return 1 - Math.sin(Math.acos(p));
486 };
487 var circOut = /*#__PURE__*/reversed(circIn);
488 var circInOut = /*#__PURE__*/mirrored(circOut);
489 var backIn = /*#__PURE__*/createBackIn(DEFAULT_OVERSHOOT_STRENGTH);
490 var backOut = /*#__PURE__*/reversed(backIn);
491 var backInOut = /*#__PURE__*/mirrored(backIn);
492 var anticipate = /*#__PURE__*/createAnticipateEasing(DEFAULT_OVERSHOOT_STRENGTH);
493 var BOUNCE_FIRST_THRESHOLD = 4.0 / 11.0;
494 var BOUNCE_SECOND_THRESHOLD = 8.0 / 11.0;
495 var BOUNCE_THIRD_THRESHOLD = 9.0 / 10.0;
496 var ca = 4356.0 / 361.0;
497 var cb = 35442.0 / 1805.0;
498 var cc = 16061.0 / 1805.0;
499 var bounceOut = function (p) {
500 var p2 = p * p;
501 return p < BOUNCE_FIRST_THRESHOLD ? 7.5625 * p2 : p < BOUNCE_SECOND_THRESHOLD ? 9.075 * p2 - 9.9 * p + 3.4 : p < BOUNCE_THIRD_THRESHOLD ? ca * p2 - cb * p + cc : 10.8 * p * p - 20.52 * p + 10.72;
502 };
503 var bounceIn = function (p) {
504 return 1.0 - bounceOut(1.0 - p);
505 };
506 var bounceInOut = function (p) {
507 return p < 0.5 ? 0.5 * (1.0 - bounceOut(1.0 - p * 2.0)) : 0.5 * bounceOut(p * 2.0 - 1.0) + 0.5;
508 };
509 var NEWTON_ITERATIONS = 8;
510 var NEWTON_MIN_SLOPE = 0.001;
511 var SUBDIVISION_PRECISION = 0.0000001;
512 var SUBDIVISION_MAX_ITERATIONS = 10;
513 var K_SPLINE_TABLE_SIZE = 11;
514 var K_SAMPLE_STEP_SIZE = 1.0 / (K_SPLINE_TABLE_SIZE - 1.0);
515 var FLOAT_32_SUPPORTED = typeof Float32Array !== 'undefined';
516 var a = function (a1, a2) {
517 return 1.0 - 3.0 * a2 + 3.0 * a1;
518 };
519 var b = function (a1, a2) {
520 return 3.0 * a2 - 6.0 * a1;
521 };
522 var c = function (a1) {
523 return 3.0 * a1;
524 };
525 var getSlope = function (t, a1, a2) {
526 return 3.0 * a(a1, a2) * t * t + 2.0 * b(a1, a2) * t + c(a1);
527 };
528 var calcBezier = function (t, a1, a2) {
529 return ((a(a1, a2) * t + b(a1, a2)) * t + c(a1)) * t;
530 };
531 function cubicBezier(mX1, mY1, mX2, mY2) {
532 var sampleValues = FLOAT_32_SUPPORTED ? new Float32Array(K_SPLINE_TABLE_SIZE) : new Array(K_SPLINE_TABLE_SIZE);
533 var binarySubdivide = function (aX, aA, aB) {
534 var i = 0;
535 var currentX;
536 var currentT;
537 do {
538 currentT = aA + (aB - aA) / 2.0;
539 currentX = calcBezier(currentT, mX1, mX2) - aX;
540 if (currentX > 0.0) {
541 aB = currentT;
542 } else {
543 aA = currentT;
544 }
545 } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
546 return currentT;
547 };
548 var newtonRaphsonIterate = function (aX, aGuessT) {
549 var i = 0;
550 var currentSlope = 0;
551 var currentX;
552 for (; i < NEWTON_ITERATIONS; ++i) {
553 currentSlope = getSlope(aGuessT, mX1, mX2);
554 if (currentSlope === 0.0) {
555 return aGuessT;
556 }
557 currentX = calcBezier(aGuessT, mX1, mX2) - aX;
558 aGuessT -= currentX / currentSlope;
559 }
560 return aGuessT;
561 };
562 var calcSampleValues = function () {
563 for (var i = 0; i < K_SPLINE_TABLE_SIZE; ++i) {
564 sampleValues[i] = calcBezier(i * K_SAMPLE_STEP_SIZE, mX1, mX2);
565 }
566 };
567 var getTForX = function (aX) {
568 var intervalStart = 0.0;
569 var currentSample = 1;
570 var lastSample = K_SPLINE_TABLE_SIZE - 1;
571 var dist = 0.0;
572 var guessForT = 0.0;
573 var initialSlope = 0.0;
574 for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
575 intervalStart += K_SAMPLE_STEP_SIZE;
576 }
577 --currentSample;
578 dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
579 guessForT = intervalStart + dist * K_SAMPLE_STEP_SIZE;
580 initialSlope = getSlope(guessForT, mX1, mX2);
581 if (initialSlope >= NEWTON_MIN_SLOPE) {
582 return newtonRaphsonIterate(aX, guessForT);
583 } else if (initialSlope === 0.0) {
584 return guessForT;
585 } else {
586 return binarySubdivide(aX, intervalStart, intervalStart + K_SAMPLE_STEP_SIZE);
587 }
588 };
589 calcSampleValues();
590 var resolver = function (aX) {
591 var returnValue;
592 if (mX1 === mY1 && mX2 === mY2) {
593 returnValue = aX;
594 } else if (aX === 0) {
595 returnValue = 0;
596 } else if (aX === 1) {
597 returnValue = 1;
598 } else {
599 returnValue = calcBezier(getTForX(aX), mY1, mY2);
600 }
601 return returnValue;
602 };
603 return resolver;
604 }
605
606 var easingLookup = /*#__PURE__*/Object.freeze({
607 reversed: reversed,
608 mirrored: mirrored,
609 createReversedEasing: createReversedEasing,
610 createMirroredEasing: createMirroredEasing,
611 createExpoIn: createExpoIn,
612 createBackIn: createBackIn,
613 createAnticipateEasing: createAnticipateEasing,
614 linear: linear,
615 easeIn: easeIn,
616 easeOut: easeOut,
617 easeInOut: easeInOut,
618 circIn: circIn,
619 circOut: circOut,
620 circInOut: circInOut,
621 backIn: backIn,
622 backOut: backOut,
623 backInOut: backInOut,
624 anticipate: anticipate,
625 bounceOut: bounceOut,
626 bounceIn: bounceIn,
627 bounceInOut: bounceInOut,
628 cubicBezier: cubicBezier
629 });
630
631 var zeroPoint = {
632 x: 0,
633 y: 0,
634 z: 0
635 };
636 var isNum = function (v) { return typeof v === 'number'; };
637
638 var curryRange = (function (func) { return function (min, max, v) { return (v !== undefined ? func(min, max, v) : function (cv) { return func(min, max, cv); }); }; });
639
640 var clamp$1 = function (min, max, v) {
641 return Math.min(Math.max(v, min), max);
642 };
643 var clamp$1$1 = curryRange(clamp$1);
644
645 var isPoint = (function (point) {
646 return point.hasOwnProperty('x') && point.hasOwnProperty('y');
647 });
648
649 var isPoint3D = (function (point) {
650 return isPoint(point) && point.hasOwnProperty('z');
651 });
652
653 var distance1D = function (a, b) { return Math.abs(a - b); };
654 var distance = (function (a, b) {
655 if (b === void 0) { b = zeroPoint; }
656 if (isNum(a) && isNum(b)) {
657 return distance1D(a, b);
658 }
659 else if (isPoint(a) && isPoint(b)) {
660 var xDelta = distance1D(a.x, b.x);
661 var yDelta = distance1D(a.y, b.y);
662 var zDelta = isPoint3D(a) && isPoint3D(b) ? distance1D(a.z, b.z) : 0;
663 return Math.sqrt(Math.pow(xDelta, 2) + Math.pow(yDelta, 2) + Math.pow(zDelta, 2));
664 }
665 return 0;
666 });
667
668 var progress = (function (from, to, value) {
669 var toFromDifference = to - from;
670 return toFromDifference === 0 ? 1 : (value - from) / toFromDifference;
671 });
672
673 var mix = (function (from, to, progress) {
674 return -progress * from + progress * to + from;
675 });
676
677 /*! *****************************************************************************
678 Copyright (c) Microsoft Corporation. All rights reserved.
679 Licensed under the Apache License, Version 2.0 (the "License"); you may not use
680 this file except in compliance with the License. You may obtain a copy of the
681 License at http://www.apache.org/licenses/LICENSE-2.0
682
683 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
684 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
685 WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
686 MERCHANTABLITY OR NON-INFRINGEMENT.
687
688 See the Apache Version 2.0 License for specific language governing permissions
689 and limitations under the License.
690 ***************************************************************************** */
691
692 var __assign$2 = function() {
693 __assign$2 = Object.assign || function __assign(t) {
694 for (var s, i = 1, n = arguments.length; i < n; i++) {
695 s = arguments[i];
696 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
697 }
698 return t;
699 };
700 return __assign$2.apply(this, arguments);
701 };
702
703 var mixLinearColor = function (from, to, v) {
704 var fromExpo = from * from;
705 var toExpo = to * to;
706 return Math.sqrt(Math.max(0, v * (toExpo - fromExpo) + fromExpo));
707 };
708 var colorTypes = [hex, rgba, hsla];
709 var getColorType = function (v) {
710 return colorTypes.find(function (type) { return type.test(v); });
711 };
712 var notAnimatable = function (color$$1) {
713 return "'" + color$$1 + "' is not an animatable color. Use the equivalent color code instead.";
714 };
715 var mixColor = (function (from, to) {
716 var fromColorType = getColorType(from);
717 var toColorType = getColorType(to);
718 invariant(!!fromColorType, notAnimatable(from));
719 invariant(!!toColorType, notAnimatable(to));
720 invariant(fromColorType.transform === toColorType.transform, 'Both colors must be hex/RGBA, OR both must be HSLA.');
721 var fromColor = fromColorType.parse(from);
722 var toColor = toColorType.parse(to);
723 var blended = __assign$2({}, fromColor);
724 var mixFunc = fromColorType === hsla ? mix : mixLinearColor;
725 return function (v) {
726 for (var key in blended) {
727 if (key !== 'alpha') {
728 blended[key] = mixFunc(fromColor[key], toColor[key], v);
729 }
730 }
731 blended.alpha = mix(fromColor.alpha, toColor.alpha, v);
732 return fromColorType.transform(blended);
733 };
734 });
735
736 var combineFunctions = function (a, b) { return function (v) { return b(a(v)); }; };
737 var pipe = (function () {
738 var transformers = [];
739 for (var _i = 0; _i < arguments.length; _i++) {
740 transformers[_i] = arguments[_i];
741 }
742 return transformers.reduce(combineFunctions);
743 });
744
745 function getMixer(origin, target) {
746 if (isNum(origin)) {
747 return function (v) { return mix(origin, target, v); };
748 }
749 else if (color.test(origin)) {
750 return mixColor(origin, target);
751 }
752 else {
753 return mixComplex(origin, target);
754 }
755 }
756 var mixArray = function (from, to) {
757 var output = from.slice();
758 var numValues = output.length;
759 var blendValue = from.map(function (fromThis, i) { return getMixer(fromThis, to[i]); });
760 return function (v) {
761 for (var i = 0; i < numValues; i++) {
762 output[i] = blendValue[i](v);
763 }
764 return output;
765 };
766 };
767 var mixObject = function (origin, target) {
768 var output = __assign$2({}, origin, target);
769 var blendValue = {};
770 for (var key in output) {
771 if (origin[key] !== undefined && target[key] !== undefined) {
772 blendValue[key] = getMixer(origin[key], target[key]);
773 }
774 }
775 return function (v) {
776 for (var key in blendValue) {
777 output[key] = blendValue[key](v);
778 }
779 return output;
780 };
781 };
782 function analyse(value) {
783 var parsed = complex.parse(value);
784 var numValues = parsed.length;
785 var numNumbers = 0;
786 var numRGB = 0;
787 var numHSL = 0;
788 for (var i = 0; i < numValues; i++) {
789 if (numNumbers || typeof parsed[i] === 'number') {
790 numNumbers++;
791 }
792 else {
793 if (parsed[i].hue !== undefined) {
794 numHSL++;
795 }
796 else {
797 numRGB++;
798 }
799 }
800 }
801 return { parsed: parsed, numNumbers: numNumbers, numRGB: numRGB, numHSL: numHSL };
802 }
803 var mixComplex = function (origin, target) {
804 var template = complex.createTransformer(target);
805 var originStats = analyse(origin);
806 var targetStats = analyse(target);
807 invariant(originStats.numHSL === targetStats.numHSL &&
808 originStats.numRGB === targetStats.numRGB &&
809 originStats.numNumbers >= targetStats.numNumbers, "Complex values '" + origin + "' and '" + target + "' too different to mix. Ensure all colors are of the same type.");
810 return pipe(mixArray(originStats.parsed, targetStats.parsed), template);
811 };
812
813 var mixNumber = function (from, to) { return function (p) { return mix(from, to, p); }; };
814 function detectMixerFactory(v) {
815 if (typeof v === 'number') {
816 return mixNumber;
817 }
818 else if (typeof v === 'string') {
819 if (color.test(v)) {
820 return mixColor;
821 }
822 else {
823 return mixComplex;
824 }
825 }
826 else if (Array.isArray(v)) {
827 return mixArray;
828 }
829 else if (typeof v === 'object') {
830 return mixObject;
831 }
832 }
833 function createMixers(output, ease, customMixer) {
834 var mixers = [];
835 var mixerFactory = customMixer || detectMixerFactory(output[0]);
836 var numMixers = output.length - 1;
837 for (var i = 0; i < numMixers; i++) {
838 var mixer = mixerFactory(output[i], output[i + 1]);
839 if (ease) {
840 var easingFunction = Array.isArray(ease) ? ease[i] : ease;
841 mixer = pipe(easingFunction, mixer);
842 }
843 mixers.push(mixer);
844 }
845 return mixers;
846 }
847 function fastInterpolate(_a, _b) {
848 var from = _a[0], to = _a[1];
849 var mixer = _b[0];
850 return function (v) { return mixer(progress(from, to, v)); };
851 }
852 function slowInterpolate(input, mixers) {
853 var inputLength = input.length;
854 var lastInputIndex = inputLength - 1;
855 return function (v) {
856 var mixerIndex = 0;
857 var foundMixerIndex = false;
858 if (v <= input[0]) {
859 foundMixerIndex = true;
860 }
861 else if (v >= input[lastInputIndex]) {
862 mixerIndex = lastInputIndex - 1;
863 foundMixerIndex = true;
864 }
865 if (!foundMixerIndex) {
866 var i = 1;
867 for (; i < inputLength; i++) {
868 if (input[i] > v || i === lastInputIndex) {
869 break;
870 }
871 }
872 mixerIndex = i - 1;
873 }
874 var progressInRange = progress(input[mixerIndex], input[mixerIndex + 1], v);
875 return mixers[mixerIndex](progressInRange);
876 };
877 }
878 function interpolate(input, output, _a) {
879 var _b = _a === void 0 ? {} : _a, _c = _b.clamp, clamp = _c === void 0 ? true : _c, ease = _b.ease, mixer = _b.mixer;
880 var inputLength = input.length;
881 invariant(inputLength === output.length, 'Both input and output ranges must be the same length');
882 invariant(!ease || !Array.isArray(ease) || ease.length === inputLength - 1, 'Array of easing functions must be of length `input.length - 1`, as it applies to the transitions **between** the defined values.');
883 if (input[0] > input[inputLength - 1]) {
884 input = [].concat(input);
885 output = [].concat(output);
886 input.reverse();
887 output.reverse();
888 }
889 var mixers = createMixers(output, ease, mixer);
890 var interpolator = inputLength === 2
891 ? fastInterpolate(input, mixers)
892 : slowInterpolate(input, mixers);
893 return clamp
894 ? pipe(clamp$1$1(input[0], input[inputLength - 1]), interpolator)
895 : interpolator;
896 }
897
898 var velocityPerSecond = (function (velocity, frameDuration) {
899 return frameDuration ? velocity * (1000 / frameDuration) : 0;
900 });
901
902 var wrap = function (min, max, v) {
903 var rangeSize = max - min;
904 return ((((v - min) % rangeSize) + rangeSize) % rangeSize) + min;
905 };
906 var wrap$1 = curryRange(wrap);
907
908 var clampProgress = clamp$1$1(0, 1);
909
910 var isFloat = function (value) {
911 return !isNaN(parseFloat(value));
912 };
913 /**
914 * `MotionValue` is used to track the state and velocity of motion values.
915 *
916 * @public
917 */
918 var MotionValue = /** @class */ (function () {
919 /**
920 * @param init - The initiating value
921 * @param config - Optional configuration options
922 *
923 * - `transformer`: A function to transform incoming values with.
924 *
925 * @internal
926 */
927 function MotionValue(init, _a) {
928 var _this = this;
929 var _b = _a === void 0 ? {} : _a, transformer = _b.transformer, parent = _b.parent;
930 /**
931 * Duration, in milliseconds, since last updating frame.
932 *
933 * @internal
934 */
935 this.timeDelta = 0;
936 /**
937 * Timestamp of the last time this `MotionValue` was updated.
938 *
939 * @internal
940 */
941 this.lastUpdated = 0;
942 /**
943 * Tracks whether this value can output a velocity. Currently this is only true
944 * if the value is numerical, but we might be able to widen the scope here and support
945 * other value types.
946 *
947 * @internal
948 */
949 this.canTrackVelocity = false;
950 this.updateAndNotify = function (v, render) {
951 if (render === void 0) { render = true; }
952 _this.prev = _this.current;
953 _this.current = _this.transformer ? _this.transformer(v) : v;
954 if (_this.updateSubscribers && _this.prev !== _this.current) {
955 _this.updateSubscribers.forEach(_this.notifySubscriber);
956 }
957 if (_this.children) {
958 _this.children.forEach(_this.setChild);
959 }
960 if (render && _this.renderSubscribers) {
961 _this.renderSubscribers.forEach(_this.notifySubscriber);
962 }
963 // Update timestamp
964 var _a = getFrameData(), delta = _a.delta, timestamp = _a.timestamp;
965 if (_this.lastUpdated !== timestamp) {
966 _this.timeDelta = delta;
967 _this.lastUpdated = timestamp;
968 sync.postRender(_this.scheduleVelocityCheck);
969 }
970 };
971 /**
972 * Notify a subscriber with the latest value.
973 *
974 * This is an instanced and bound function to prevent generating a new
975 * function once per frame.
976 *
977 * @param subscriber - The subscriber to notify.
978 *
979 * @internal
980 */
981 this.notifySubscriber = function (subscriber) {
982 subscriber(_this.current);
983 };
984 /**
985 * Schedule a velocity check for the next frame.
986 *
987 * This is an instanced and bound function to prevent generating a new
988 * function once per frame.
989 *
990 * @internal
991 */
992 this.scheduleVelocityCheck = function () { return sync.postRender(_this.velocityCheck); };
993 /**
994 * Updates `prev` with `current` if the value hasn't been updated this frame.
995 * This ensures velocity calculations return `0`.
996 *
997 * This is an instanced and bound function to prevent generating a new
998 * function once per frame.
999 *
1000 * @internal
1001 */
1002 this.velocityCheck = function (_a) {
1003 var timestamp = _a.timestamp;
1004 if (timestamp !== _this.lastUpdated) {
1005 _this.prev = _this.current;
1006 }
1007 };
1008 /**
1009 * Updates child `MotionValue`.
1010 *
1011 * @param child - Child `MotionValue`.
1012 *
1013 * @internal
1014 */
1015 this.setChild = function (child) { return child.set(_this.current); };
1016 this.parent = parent;
1017 this.transformer = transformer;
1018 this.set(init, false);
1019 this.canTrackVelocity = isFloat(this.current);
1020 }
1021 /**
1022 * Creates a new `MotionValue` that's subscribed to the output of this one.
1023 *
1024 * @param config - Optional configuration options
1025 *
1026 * - `transformer`: A function to transform incoming values with.
1027 *
1028 * @internal
1029 */
1030 MotionValue.prototype.addChild = function (config) {
1031 if (config === void 0) { config = {}; }
1032 var child = new MotionValue(this.current, __assign({ parent: this }, config));
1033 if (!this.children)
1034 this.children = new Set();
1035 this.children.add(child);
1036 return child;
1037 };
1038 /**
1039 * Stops a `MotionValue` from being subscribed to this one.
1040 *
1041 * @param child - The subscribed `MotionValue`
1042 *
1043 * @internal
1044 */
1045 MotionValue.prototype.removeChild = function (child) {
1046 if (!this.children) {
1047 return;
1048 }
1049 this.children.delete(child);
1050 };
1051 /**
1052 * Subscribes a subscriber function to a subscription list.
1053 *
1054 * @param subscriptions - A `Set` of subscribers.
1055 * @param subscription - A subscriber function.
1056 */
1057 MotionValue.prototype.subscribeTo = function (subscriptions, subscription) {
1058 var _this = this;
1059 var updateSubscriber = function () { return subscription(_this.current); };
1060 subscriptions.add(updateSubscriber);
1061 return function () { return subscriptions.delete(updateSubscriber); };
1062 };
1063 /**
1064 * Adds a function that will be notified when the `MotionValue` is updated.
1065 *
1066 * It returns a function that, when called, will cancel the subscription.
1067 *
1068 * When calling `onChange` inside a React component, it should be wrapped with the
1069 * `useEffect` hook. As it returns an unsubscribe function, this should be returned
1070 * from the `useEffect` function to ensure you don't add duplicate subscribers..
1071 *
1072 * @library
1073 *
1074 * ```jsx
1075 * function MyComponent() {
1076 * const x = useMotionValue(0)
1077 * const y = useMotionValue(0)
1078 * const opacity = useMotionValue(1)
1079 *
1080 * useEffect(() => {
1081 * function updateOpacity() {
1082 * const maxXY = Math.max(x.get(), y.get())
1083 * const newOpacity = transform(maxXY, [0, 100], [1, 0])
1084 * opacity.set(newOpacity)
1085 * }
1086 *
1087 * const unsubscribeX = x.onChange(updateOpacity)
1088 * const unsubscribeY = y.onChange(updateOpacity)
1089 *
1090 * return () => {
1091 * unsubscribeX()
1092 * unsubscribeY()
1093 * }
1094 * }, [])
1095 *
1096 * return <Frame x={x} />
1097 * }
1098 * ```
1099 *
1100 * @motion
1101 *
1102 * ```jsx
1103 * export const MyComponent = () => {
1104 * const x = useMotionValue(0)
1105 * const y = useMotionValue(0)
1106 * const opacity = useMotionValue(1)
1107 *
1108 * useEffect(() => {
1109 * function updateOpacity() {
1110 * const maxXY = Math.max(x.get(), y.get())
1111 * const newOpacity = transform(maxXY, [0, 100], [1, 0])
1112 * opacity.set(newOpacity)
1113 * }
1114 *
1115 * const unsubscribeX = x.onChange(updateOpacity)
1116 * const unsubscribeY = y.onChange(updateOpacity)
1117 *
1118 * return () => {
1119 * unsubscribeX()
1120 * unsubscribeY()
1121 * }
1122 * }, [])
1123 *
1124 * return <motion.div style={{ x }} />
1125 * }
1126 * ```
1127 *
1128 * @internalremarks
1129 *
1130 * We could look into a `useOnChange` hook if the above lifecycle management proves confusing.
1131 *
1132 * ```jsx
1133 * useOnChange(x, () => {})
1134 * ```
1135 *
1136 * @param subscriber - A function that receives the latest value.
1137 * @returns A function that, when called, will cancel this subscription.
1138 *
1139 * @public
1140 */
1141 MotionValue.prototype.onChange = function (subscription) {
1142 if (!this.updateSubscribers)
1143 this.updateSubscribers = new Set();
1144 return this.subscribeTo(this.updateSubscribers, subscription);
1145 };
1146 /**
1147 * Adds a function that will be notified when the `MotionValue` requests a render.
1148 *
1149 * @param subscriber - A function that's provided the latest value.
1150 * @returns A function that, when called, will cancel this subscription.
1151 *
1152 * @internal
1153 */
1154 MotionValue.prototype.onRenderRequest = function (subscription) {
1155 if (!this.renderSubscribers)
1156 this.renderSubscribers = new Set();
1157 // Render immediately
1158 this.notifySubscriber(subscription);
1159 return this.subscribeTo(this.renderSubscribers, subscription);
1160 };
1161 /**
1162 * Attaches a passive effect to the `MotionValue`.
1163 *
1164 * @internal
1165 */
1166 MotionValue.prototype.attach = function (passiveEffect) {
1167 this.passiveEffect = passiveEffect;
1168 };
1169 /**
1170 * Sets the state of the `MotionValue`.
1171 *
1172 * @remarks
1173 *
1174 * ```jsx
1175 * const x = useMotionValue(0)
1176 * x.set(10)
1177 * ```
1178 *
1179 * @param latest - Latest value to set.
1180 * @param render - Whether to notify render subscribers. Defaults to `true`
1181 *
1182 * @public
1183 */
1184 MotionValue.prototype.set = function (v, render) {
1185 if (render === void 0) { render = true; }
1186 if (!render || !this.passiveEffect) {
1187 this.updateAndNotify(v, render);
1188 }
1189 else {
1190 this.passiveEffect(v, this.updateAndNotify);
1191 }
1192 };
1193 /**
1194 * Returns the latest state of `MotionValue`
1195 *
1196 * @returns - The latest state of `MotionValue`
1197 *
1198 * @public
1199 */
1200 MotionValue.prototype.get = function () {
1201 return this.current;
1202 };
1203 /**
1204 * Returns the latest velocity of `MotionValue`
1205 *
1206 * @returns - The latest velocity of `MotionValue`. Returns `0` if the state is non-numerical.
1207 *
1208 * @public
1209 */
1210 MotionValue.prototype.getVelocity = function () {
1211 // This could be isFloat(this.prev) && isFloat(this.current), but that would be wasteful
1212 return this.canTrackVelocity
1213 ? // These casts could be avoided if parseFloat would be typed better
1214 velocityPerSecond(parseFloat(this.current) -
1215 parseFloat(this.prev), this.timeDelta)
1216 : 0;
1217 };
1218 /**
1219 * Registers a new animation to control this `MotionValue`. Only one
1220 * animation can drive a `MotionValue` at one time.
1221 *
1222 * ```jsx
1223 * value.start()
1224 * ```
1225 *
1226 * @param animation - A function that starts the provided animation
1227 *
1228 * @internal
1229 */
1230 MotionValue.prototype.start = function (animation) {
1231 var _this = this;
1232 this.stop();
1233 return new Promise(function (resolve) {
1234 _this.stopAnimation = animation(resolve);
1235 }).then(function () { return _this.clearAnimation(); });
1236 };
1237 /**
1238 * Stop the currently active animation.
1239 *
1240 * @public
1241 */
1242 MotionValue.prototype.stop = function () {
1243 if (this.stopAnimation)
1244 this.stopAnimation();
1245 this.clearAnimation();
1246 };
1247 /**
1248 * Returns `true` if this value is currently animating.
1249 *
1250 * @public
1251 */
1252 MotionValue.prototype.isAnimating = function () {
1253 return !!this.stopAnimation;
1254 };
1255 MotionValue.prototype.clearAnimation = function () {
1256 this.stopAnimation = null;
1257 };
1258 /**
1259 * Destroy and clean up subscribers to this `MotionValue`.
1260 *
1261 * The `MotionValue` hooks like `useMotionValue` and `useTransform` automatically
1262 * handle the lifecycle of the returned `MotionValue`, so this method is only necessary if you've manually
1263 * created a `MotionValue` via the `motionValue` function.
1264 *
1265 * @public
1266 */
1267 MotionValue.prototype.destroy = function () {
1268 this.updateSubscribers && this.updateSubscribers.clear();
1269 this.renderSubscribers && this.renderSubscribers.clear();
1270 this.parent && this.parent.removeChild(this);
1271 this.stop();
1272 };
1273 return MotionValue;
1274 }());
1275 /**
1276 * @internal
1277 */
1278 function motionValue(init, opts) {
1279 return new MotionValue(init, opts);
1280 }
1281
1282 /*! *****************************************************************************
1283 Copyright (c) Microsoft Corporation. All rights reserved.
1284 Licensed under the Apache License, Version 2.0 (the "License"); you may not use
1285 this file except in compliance with the License. You may obtain a copy of the
1286 License at http://www.apache.org/licenses/LICENSE-2.0
1287
1288 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1289 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
1290 WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
1291 MERCHANTABLITY OR NON-INFRINGEMENT.
1292
1293 See the Apache Version 2.0 License for specific language governing permissions
1294 and limitations under the License.
1295 ***************************************************************************** */
1296
1297 var __assign$3 = function() {
1298 __assign$3 = Object.assign || function __assign(t) {
1299 for (var s, i = 1, n = arguments.length; i < n; i++) {
1300 s = arguments[i];
1301 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
1302 }
1303 return t;
1304 };
1305 return __assign$3.apply(this, arguments);
1306 };
1307
1308 var clamp$2 = function (min, max) { return function (v) {
1309 return Math.max(Math.min(v, max), min);
1310 }; };
1311 var sanitize$1 = function (v) { return (v % 1 ? Number(v.toFixed(5)) : v); };
1312 var singleColorRegex$1 = /^(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))$/i;
1313
1314 var number$1 = {
1315 test: function (v) { return typeof v === 'number'; },
1316 parse: parseFloat,
1317 transform: function (v) { return v; }
1318 };
1319 var alpha$1 = __assign$3(__assign$3({}, number$1), { transform: clamp$2(0, 1) });
1320 var scale$1 = __assign$3(__assign$3({}, number$1), { default: 1 });
1321
1322 var createUnitType$1 = function (unit) { return ({
1323 test: function (v) {
1324 return typeof v === 'string' && v.endsWith(unit) && v.split(' ').length === 1;
1325 },
1326 parse: parseFloat,
1327 transform: function (v) { return "" + v + unit; }
1328 }); };
1329 var degrees$1 = createUnitType$1('deg');
1330 var percent$1 = createUnitType$1('%');
1331 var px$1 = createUnitType$1('px');
1332 var progressPercentage$1 = __assign$3(__assign$3({}, percent$1), { parse: function (v) { return percent$1.parse(v) / 100; }, transform: function (v) { return percent$1.transform(v * 100); } });
1333
1334 var getValueFromFunctionString$1 = function (value) {
1335 return value.substring(value.indexOf('(') + 1, value.lastIndexOf(')'));
1336 };
1337 var clampRgbUnit$1 = clamp$2(0, 255);
1338 var isRgba$1 = function (v) { return v.red !== undefined; };
1339 var isHsla$1 = function (v) { return v.hue !== undefined; };
1340 var splitColorValues$1 = function (terms) {
1341 return function (v) {
1342 if (typeof v !== 'string')
1343 return v;
1344 var values = {};
1345 var valuesArray = getValueFromFunctionString$1(v).split(/,\s*/);
1346 for (var i = 0; i < 4; i++) {
1347 values[terms[i]] =
1348 valuesArray[i] !== undefined ? parseFloat(valuesArray[i]) : 1;
1349 }
1350 return values;
1351 };
1352 };
1353 var rgbaTemplate$1 = function (_a) {
1354 var red = _a.red, green = _a.green, blue = _a.blue, _b = _a.alpha, alpha$$1 = _b === void 0 ? 1 : _b;
1355 return "rgba(" + red + ", " + green + ", " + blue + ", " + alpha$$1 + ")";
1356 };
1357 var hslaTemplate$1 = function (_a) {
1358 var hue = _a.hue, saturation = _a.saturation, lightness = _a.lightness, _b = _a.alpha, alpha$$1 = _b === void 0 ? 1 : _b;
1359 return "hsla(" + hue + ", " + saturation + ", " + lightness + ", " + alpha$$1 + ")";
1360 };
1361 var rgbUnit$1 = __assign$3(__assign$3({}, number$1), { transform: function (v) { return Math.round(clampRgbUnit$1(v)); } });
1362 function isColorString$1(color, colorType) {
1363 return color.startsWith(colorType) && singleColorRegex$1.test(color);
1364 }
1365 var rgba$1 = {
1366 test: function (v) { return (typeof v === 'string' ? isColorString$1(v, 'rgb') : isRgba$1(v)); },
1367 parse: splitColorValues$1(['red', 'green', 'blue', 'alpha']),
1368 transform: function (_a) {
1369 var red = _a.red, green = _a.green, blue = _a.blue, _b = _a.alpha, alpha$$1 = _b === void 0 ? 1 : _b;
1370 return rgbaTemplate$1({
1371 red: rgbUnit$1.transform(red),
1372 green: rgbUnit$1.transform(green),
1373 blue: rgbUnit$1.transform(blue),
1374 alpha: sanitize$1(alpha$1.transform(alpha$$1))
1375 });
1376 }
1377 };
1378 var hsla$1 = {
1379 test: function (v) { return (typeof v === 'string' ? isColorString$1(v, 'hsl') : isHsla$1(v)); },
1380 parse: splitColorValues$1(['hue', 'saturation', 'lightness', 'alpha']),
1381 transform: function (_a) {
1382 var hue = _a.hue, saturation = _a.saturation, lightness = _a.lightness, _b = _a.alpha, alpha$$1 = _b === void 0 ? 1 : _b;
1383 return hslaTemplate$1({
1384 hue: Math.round(hue),
1385 saturation: percent$1.transform(sanitize$1(saturation)),
1386 lightness: percent$1.transform(sanitize$1(lightness)),
1387 alpha: sanitize$1(alpha$1.transform(alpha$$1))
1388 });
1389 }
1390 };
1391 var hex$1 = __assign$3(__assign$3({}, rgba$1), { test: function (v) { return typeof v === 'string' && isColorString$1(v, '#'); }, parse: function (v) {
1392 var r = '';
1393 var g = '';
1394 var b = '';
1395 if (v.length > 4) {
1396 r = v.substr(1, 2);
1397 g = v.substr(3, 2);
1398 b = v.substr(5, 2);
1399 }
1400 else {
1401 r = v.substr(1, 1);
1402 g = v.substr(2, 1);
1403 b = v.substr(3, 1);
1404 r += r;
1405 g += g;
1406 b += b;
1407 }
1408 return {
1409 red: parseInt(r, 16),
1410 green: parseInt(g, 16),
1411 blue: parseInt(b, 16),
1412 alpha: 1
1413 };
1414 } });
1415 var color$1 = {
1416 test: function (v) {
1417 return (typeof v === 'string' && singleColorRegex$1.test(v)) ||
1418 isRgba$1(v) ||
1419 isHsla$1(v);
1420 },
1421 parse: function (v) {
1422 if (rgba$1.test(v)) {
1423 return rgba$1.parse(v);
1424 }
1425 else if (hsla$1.test(v)) {
1426 return hsla$1.parse(v);
1427 }
1428 else if (hex$1.test(v)) {
1429 return hex$1.parse(v);
1430 }
1431 return v;
1432 },
1433 transform: function (v) {
1434 if (isRgba$1(v)) {
1435 return rgba$1.transform(v);
1436 }
1437 else if (isHsla$1(v)) {
1438 return hsla$1.transform(v);
1439 }
1440 return v;
1441 }
1442 };
1443
1444 var createStyler = function (_a) {
1445 var onRead = _a.onRead,
1446 onRender = _a.onRender,
1447 _b = _a.uncachedValues,
1448 uncachedValues = _b === void 0 ? new Set() : _b,
1449 _c = _a.useCache,
1450 useCache = _c === void 0 ? true : _c;
1451 return function (_a) {
1452 if (_a === void 0) {
1453 _a = {};
1454 }
1455 var props = __rest(_a, []);
1456 var state = {};
1457 var changedValues = [];
1458 var hasChanged = false;
1459 function setValue(key, value) {
1460 if (key.startsWith('--')) {
1461 props.hasCSSVariable = true;
1462 }
1463 var currentValue = state[key];
1464 state[key] = value;
1465 if (state[key] === currentValue) return;
1466 if (changedValues.indexOf(key) === -1) {
1467 changedValues.push(key);
1468 }
1469 if (!hasChanged) {
1470 hasChanged = true;
1471 sync.render(styler.render);
1472 }
1473 }
1474 var styler = {
1475 get: function (key, forceRead) {
1476 if (forceRead === void 0) {
1477 forceRead = false;
1478 }
1479 var useCached = !forceRead && useCache && !uncachedValues.has(key) && state[key] !== undefined;
1480 return useCached ? state[key] : onRead(key, props);
1481 },
1482 set: function (values, value) {
1483 if (typeof values === 'string') {
1484 setValue(values, value);
1485 } else {
1486 for (var key in values) {
1487 setValue(key, values[key]);
1488 }
1489 }
1490 return this;
1491 },
1492 render: function (forceRender) {
1493 if (forceRender === void 0) {
1494 forceRender = false;
1495 }
1496 if (hasChanged || forceRender === true) {
1497 onRender(state, props, changedValues);
1498 hasChanged = false;
1499 changedValues.length = 0;
1500 }
1501 return this;
1502 }
1503 };
1504 return styler;
1505 };
1506 };
1507
1508 var CAMEL_CASE_PATTERN = /([a-z])([A-Z])/g;
1509 var REPLACE_TEMPLATE = '$1-$2';
1510 var camelToDash = function (str) {
1511 return str.replace(CAMEL_CASE_PATTERN, REPLACE_TEMPLATE).toLowerCase();
1512 };
1513
1514 var camelCache = /*#__PURE__*/new Map();
1515 var dashCache = /*#__PURE__*/new Map();
1516 var prefixes = ['Webkit', 'Moz', 'O', 'ms', ''];
1517 var numPrefixes = prefixes.length;
1518 var isBrowser = typeof document !== 'undefined';
1519 var testElement;
1520 var setDashPrefix = function (key, prefixed) {
1521 return dashCache.set(key, camelToDash(prefixed));
1522 };
1523 var testPrefix = function (key) {
1524 testElement = testElement || document.createElement('div');
1525 for (var i = 0; i < numPrefixes; i++) {
1526 var prefix = prefixes[i];
1527 var noPrefix = prefix === '';
1528 var prefixedPropertyName = noPrefix ? key : prefix + key.charAt(0).toUpperCase() + key.slice(1);
1529 if (prefixedPropertyName in testElement.style || noPrefix) {
1530 if (noPrefix && key === 'clipPath' && dashCache.has(key)) {
1531 return;
1532 }
1533 camelCache.set(key, prefixedPropertyName);
1534 setDashPrefix(key, "" + (noPrefix ? '' : '-') + camelToDash(prefixedPropertyName));
1535 }
1536 }
1537 };
1538 var setServerProperty = function (key) {
1539 return setDashPrefix(key, key);
1540 };
1541 var prefixer = function (key, asDashCase) {
1542 if (asDashCase === void 0) {
1543 asDashCase = false;
1544 }
1545 var cache = asDashCase ? dashCache : camelCache;
1546 if (!cache.has(key)) {
1547 isBrowser ? testPrefix(key) : setServerProperty(key);
1548 }
1549 return cache.get(key) || key;
1550 };
1551
1552 var axes = ['', 'X', 'Y', 'Z'];
1553 var order = ['translate', 'scale', 'rotate', 'skew', 'transformPerspective'];
1554 var transformProps = /*#__PURE__*/order.reduce(function (acc, key) {
1555 return axes.reduce(function (axesAcc, axesKey) {
1556 axesAcc.push(key + axesKey);
1557 return axesAcc;
1558 }, acc);
1559 }, ['x', 'y', 'z']);
1560 var transformPropDictionary = /*#__PURE__*/transformProps.reduce(function (dict, key) {
1561 dict[key] = true;
1562 return dict;
1563 }, {});
1564 function isTransformProp(key) {
1565 return transformPropDictionary[key] === true;
1566 }
1567 function sortTransformProps(a, b) {
1568 return transformProps.indexOf(a) - transformProps.indexOf(b);
1569 }
1570 var transformOriginProps = /*#__PURE__*/new Set(['originX', 'originY', 'originZ']);
1571 function isTransformOriginProp(key) {
1572 return transformOriginProps.has(key);
1573 }
1574
1575 var int = /*#__PURE__*/__assign( /*#__PURE__*/__assign({}, number$1), { transform: Math.round });
1576 var valueTypes = {
1577 color: color$1,
1578 backgroundColor: color$1,
1579 outlineColor: color$1,
1580 fill: color$1,
1581 stroke: color$1,
1582 borderColor: color$1,
1583 borderTopColor: color$1,
1584 borderRightColor: color$1,
1585 borderBottomColor: color$1,
1586 borderLeftColor: color$1,
1587 borderWidth: px$1,
1588 borderTopWidth: px$1,
1589 borderRightWidth: px$1,
1590 borderBottomWidth: px$1,
1591 borderLeftWidth: px$1,
1592 borderRadius: px$1,
1593 radius: px$1,
1594 borderTopLeftRadius: px$1,
1595 borderTopRightRadius: px$1,
1596 borderBottomRightRadius: px$1,
1597 borderBottomLeftRadius: px$1,
1598 width: px$1,
1599 maxWidth: px$1,
1600 height: px$1,
1601 maxHeight: px$1,
1602 size: px$1,
1603 top: px$1,
1604 right: px$1,
1605 bottom: px$1,
1606 left: px$1,
1607 padding: px$1,
1608 paddingTop: px$1,
1609 paddingRight: px$1,
1610 paddingBottom: px$1,
1611 paddingLeft: px$1,
1612 margin: px$1,
1613 marginTop: px$1,
1614 marginRight: px$1,
1615 marginBottom: px$1,
1616 marginLeft: px$1,
1617 rotate: degrees$1,
1618 rotateX: degrees$1,
1619 rotateY: degrees$1,
1620 rotateZ: degrees$1,
1621 scale: scale$1,
1622 scaleX: scale$1,
1623 scaleY: scale$1,
1624 scaleZ: scale$1,
1625 skew: degrees$1,
1626 skewX: degrees$1,
1627 skewY: degrees$1,
1628 distance: px$1,
1629 translateX: px$1,
1630 translateY: px$1,
1631 translateZ: px$1,
1632 x: px$1,
1633 y: px$1,
1634 z: px$1,
1635 perspective: px$1,
1636 opacity: alpha$1,
1637 originX: progressPercentage$1,
1638 originY: progressPercentage$1,
1639 originZ: px$1,
1640 zIndex: int,
1641 fillOpacity: alpha$1,
1642 strokeOpacity: alpha$1,
1643 numOctaves: int
1644 };
1645 var getValueType = function (key) {
1646 return valueTypes[key];
1647 };
1648 var getValueAsType = function (value, type) {
1649 return type && typeof value === 'number' ? type.transform(value) : value;
1650 };
1651
1652 var SCROLL_LEFT = 'scrollLeft';
1653 var SCROLL_TOP = 'scrollTop';
1654 var scrollKeys = /*#__PURE__*/new Set([SCROLL_LEFT, SCROLL_TOP]);
1655
1656 var blacklist = /*#__PURE__*/new Set([SCROLL_LEFT, SCROLL_TOP, 'transform']);
1657 var translateAlias = {
1658 x: 'translateX',
1659 y: 'translateY',
1660 z: 'translateZ'
1661 };
1662 function isCustomTemplate(v) {
1663 return typeof v === 'function';
1664 }
1665 function buildTransform(state, transform, transformKeys, transformIsDefault, enableHardwareAcceleration) {
1666 var transformString = '';
1667 var transformHasZ = false;
1668 transformKeys.sort(sortTransformProps);
1669 var numTransformKeys = transformKeys.length;
1670 for (var i = 0; i < numTransformKeys; i++) {
1671 var key = transformKeys[i];
1672 transformString += (translateAlias[key] || key) + "(" + transform[key] + ") ";
1673 transformHasZ = key === 'z' ? true : transformHasZ;
1674 }
1675 if (!transformHasZ && enableHardwareAcceleration) {
1676 transformString += 'translateZ(0)';
1677 } else {
1678 transformString = transformString.trim();
1679 }
1680 if (isCustomTemplate(state.transform)) {
1681 transformString = state.transform(transform, transformIsDefault ? '' : transformString);
1682 } else if (transformIsDefault) {
1683 transformString = 'none';
1684 }
1685 return transformString;
1686 }
1687 function buildStyleProperty(state, enableHardwareAcceleration, styles, transform, transformOrigin, transformKeys, isDashCase) {
1688 if (enableHardwareAcceleration === void 0) {
1689 enableHardwareAcceleration = true;
1690 }
1691 if (styles === void 0) {
1692 styles = {};
1693 }
1694 if (transform === void 0) {
1695 transform = {};
1696 }
1697 if (transformOrigin === void 0) {
1698 transformOrigin = {};
1699 }
1700 if (transformKeys === void 0) {
1701 transformKeys = [];
1702 }
1703 if (isDashCase === void 0) {
1704 isDashCase = false;
1705 }
1706 var transformIsDefault = true;
1707 var hasTransform = false;
1708 var hasTransformOrigin = false;
1709 for (var key in state) {
1710 var value = state[key];
1711 var valueType = getValueType(key);
1712 var valueAsType = getValueAsType(value, valueType);
1713 if (isTransformProp(key)) {
1714 hasTransform = true;
1715 transform[key] = valueAsType;
1716 transformKeys.push(key);
1717 if (transformIsDefault) {
1718 if (valueType.default && value !== valueType.default || !valueType.default && value !== 0) {
1719 transformIsDefault = false;
1720 }
1721 }
1722 } else if (isTransformOriginProp(key)) {
1723 transformOrigin[key] = valueAsType;
1724 hasTransformOrigin = true;
1725 } else if (!blacklist.has(key) || !isCustomTemplate(valueAsType)) {
1726 styles[prefixer(key, isDashCase)] = valueAsType;
1727 }
1728 }
1729 if (hasTransform || typeof state.transform === 'function') {
1730 styles.transform = buildTransform(state, transform, transformKeys, transformIsDefault, enableHardwareAcceleration);
1731 }
1732 if (hasTransformOrigin) {
1733 styles.transformOrigin = (transformOrigin.originX || '50%') + " " + (transformOrigin.originY || '50%') + " " + (transformOrigin.originZ || 0);
1734 }
1735 return styles;
1736 }
1737 function createStyleBuilder(enableHardwareAcceleration, isDashCase) {
1738 if (enableHardwareAcceleration === void 0) {
1739 enableHardwareAcceleration = true;
1740 }
1741 if (isDashCase === void 0) {
1742 isDashCase = true;
1743 }
1744 var styles = {};
1745 var transform = {};
1746 var transformOrigin = {};
1747 var transformKeys = [];
1748 return function (state) {
1749 transformKeys.length = 0;
1750 buildStyleProperty(state, enableHardwareAcceleration, styles, transform, transformOrigin, transformKeys, isDashCase);
1751 return styles;
1752 };
1753 }
1754
1755 function onRead(key, options) {
1756 var element = options.element,
1757 preparseOutput = options.preparseOutput;
1758 var defaultValueType = getValueType(key);
1759 if (isTransformProp(key)) {
1760 return defaultValueType ? defaultValueType.default || 0 : 0;
1761 } else if (scrollKeys.has(key)) {
1762 return element[key];
1763 } else {
1764 var domValue = window.getComputedStyle(element, null).getPropertyValue(prefixer(key, true)) || 0;
1765 return preparseOutput && defaultValueType && defaultValueType.test(domValue) && defaultValueType.parse ? defaultValueType.parse(domValue) : domValue;
1766 }
1767 }
1768 function onRender(state, _a, changedValues) {
1769 var element = _a.element,
1770 buildStyles = _a.buildStyles,
1771 hasCSSVariable = _a.hasCSSVariable;
1772 Object.assign(element.style, buildStyles(state));
1773 if (hasCSSVariable) {
1774 var numChangedValues = changedValues.length;
1775 for (var i = 0; i < numChangedValues; i++) {
1776 var key = changedValues[i];
1777 if (key.startsWith('--')) {
1778 element.style.setProperty(key, state[key]);
1779 }
1780 }
1781 }
1782 if (changedValues.indexOf(SCROLL_LEFT) !== -1) {
1783 element[SCROLL_LEFT] = state[SCROLL_LEFT];
1784 }
1785 if (changedValues.indexOf(SCROLL_TOP) !== -1) {
1786 element[SCROLL_TOP] = state[SCROLL_TOP];
1787 }
1788 }
1789 var cssStyler = /*#__PURE__*/createStyler({
1790 onRead: onRead,
1791 onRender: onRender,
1792 uncachedValues: scrollKeys
1793 });
1794 function createCssStyler(element, _a) {
1795 if (_a === void 0) {
1796 _a = {};
1797 }
1798 var enableHardwareAcceleration = _a.enableHardwareAcceleration,
1799 props = __rest(_a, ["enableHardwareAcceleration"]);
1800 return cssStyler(__assign({ element: element, buildStyles: createStyleBuilder(enableHardwareAcceleration), preparseOutput: true }, props));
1801 }
1802
1803 var camelCaseAttributes = /*#__PURE__*/new Set(['baseFrequency', 'diffuseConstant', 'kernelMatrix', 'kernelUnitLength', 'keySplines', 'keyTimes', 'limitingConeAngle', 'markerHeight', 'markerWidth', 'numOctaves', 'targetX', 'targetY', 'surfaceScale', 'specularConstant', 'specularExponent', 'stdDeviation', 'tableValues']);
1804
1805 var defaultOrigin = 0.5;
1806 var svgAttrsTemplate = function () {
1807 return {
1808 style: {}
1809 };
1810 };
1811 var progressToPixels = function (progress, length) {
1812 return px$1.transform(progress * length);
1813 };
1814 var unmeasured = { x: 0, y: 0, width: 0, height: 0 };
1815 function calcOrigin(origin, offset, size) {
1816 return typeof origin === 'string' ? origin : px$1.transform(offset + size * origin);
1817 }
1818 function calculateSVGTransformOrigin(dimensions, originX, originY) {
1819 return calcOrigin(originX, dimensions.x, dimensions.width) + " " + calcOrigin(originY, dimensions.y, dimensions.height);
1820 }
1821 function buildSVGAttrs(_a, dimensions, totalPathLength, cssBuilder, attrs, isDashCase) {
1822 if (dimensions === void 0) {
1823 dimensions = unmeasured;
1824 }
1825 if (cssBuilder === void 0) {
1826 cssBuilder = createStyleBuilder(false, false);
1827 }
1828 if (attrs === void 0) {
1829 attrs = svgAttrsTemplate();
1830 }
1831 if (isDashCase === void 0) {
1832 isDashCase = true;
1833 }
1834 var attrX = _a.attrX,
1835 attrY = _a.attrY,
1836 originX = _a.originX,
1837 originY = _a.originY,
1838 pathLength = _a.pathLength,
1839 _b = _a.pathSpacing,
1840 pathSpacing = _b === void 0 ? 1 : _b,
1841 _c = _a.pathOffset,
1842 pathOffset = _c === void 0 ? 0 : _c,
1843 state = __rest(_a, ["attrX", "attrY", "originX", "originY", "pathLength", "pathSpacing", "pathOffset"]);
1844 var style = cssBuilder(state);
1845 for (var key in style) {
1846 if (key === 'transform') {
1847 attrs.style.transform = style[key];
1848 } else {
1849 var attrKey = isDashCase && !camelCaseAttributes.has(key) ? camelToDash(key) : key;
1850 attrs[attrKey] = style[key];
1851 }
1852 }
1853 if (originX !== undefined || originY !== undefined || style.transform) {
1854 attrs.style.transformOrigin = calculateSVGTransformOrigin(dimensions, originX !== undefined ? originX : defaultOrigin, originY !== undefined ? originY : defaultOrigin);
1855 }
1856 if (attrX !== undefined) attrs.x = attrX;
1857 if (attrY !== undefined) attrs.y = attrY;
1858 if (totalPathLength !== undefined && pathLength !== undefined) {
1859 attrs[isDashCase ? 'stroke-dashoffset' : 'strokeDashoffset'] = progressToPixels(-pathOffset, totalPathLength);
1860 attrs[isDashCase ? 'stroke-dasharray' : 'strokeDasharray'] = progressToPixels(pathLength, totalPathLength) + " " + progressToPixels(pathSpacing, totalPathLength);
1861 }
1862 return attrs;
1863 }
1864 function createAttrBuilder(dimensions, totalPathLength, isDashCase) {
1865 if (isDashCase === void 0) {
1866 isDashCase = true;
1867 }
1868 var attrs = svgAttrsTemplate();
1869 var cssBuilder = createStyleBuilder(false, false);
1870 return function (state) {
1871 return buildSVGAttrs(state, dimensions, totalPathLength, cssBuilder, attrs, isDashCase);
1872 };
1873 }
1874
1875 var getDimensions = function (element) {
1876 return typeof element.getBBox === 'function' ? element.getBBox() : element.getBoundingClientRect();
1877 };
1878 var getSVGElementDimensions = function (element) {
1879 try {
1880 return getDimensions(element);
1881 } catch (e) {
1882 return { x: 0, y: 0, width: 0, height: 0 };
1883 }
1884 };
1885
1886 var isPath = function (element) {
1887 return element.tagName === 'path';
1888 };
1889 var svgStyler = /*#__PURE__*/createStyler({
1890 onRead: function (key, _a) {
1891 var element = _a.element;
1892 key = !camelCaseAttributes.has(key) ? camelToDash(key) : key;
1893 if (!isTransformProp(key)) {
1894 return element.getAttribute(key);
1895 } else {
1896 var valueType = getValueType(key);
1897 return valueType ? valueType.default || 0 : 0;
1898 }
1899 },
1900 onRender: function (state, _a) {
1901 var element = _a.element,
1902 buildAttrs = _a.buildAttrs;
1903 var attrs = buildAttrs(state);
1904 for (var key in attrs) {
1905 if (key === 'style') {
1906 Object.assign(element.style, attrs.style);
1907 } else {
1908 element.setAttribute(key, attrs[key]);
1909 }
1910 }
1911 }
1912 });
1913 var svg = function (element) {
1914 var dimensions = getSVGElementDimensions(element);
1915 var pathLength = isPath(element) && element.getTotalLength ? element.getTotalLength() : undefined;
1916 return svgStyler({
1917 element: element,
1918 buildAttrs: createAttrBuilder(dimensions, pathLength)
1919 });
1920 };
1921
1922 var viewport = /*#__PURE__*/createStyler({
1923 useCache: false,
1924 onRead: function (key) {
1925 return key === 'scrollTop' ? window.pageYOffset : window.pageXOffset;
1926 },
1927 onRender: function (_a) {
1928 var _b = _a.scrollTop,
1929 scrollTop = _b === void 0 ? 0 : _b,
1930 _c = _a.scrollLeft,
1931 scrollLeft = _c === void 0 ? 0 : _c;
1932 return window.scrollTo(scrollLeft, scrollTop);
1933 }
1934 });
1935
1936 var cache = /*#__PURE__*/new WeakMap();
1937 var isHTMLElement = function (node) {
1938 return node instanceof HTMLElement || typeof node.click === 'function';
1939 };
1940 var isSVGElement = function (node) {
1941 return node instanceof SVGElement || 'ownerSVGElement' in node;
1942 };
1943 var createDOMStyler = function (node, props) {
1944 var styler;
1945 if (node === window) {
1946 styler = viewport(node);
1947 } else if (isHTMLElement(node)) {
1948 styler = createCssStyler(node, props);
1949 } else if (isSVGElement(node)) {
1950 styler = svg(node);
1951 }
1952 invariant(styler !== undefined, 'No valid node provided. Node must be HTMLElement, SVGElement or window.');
1953 cache.set(node, styler);
1954 return styler;
1955 };
1956 var getStyler = function (node, props) {
1957 return cache.has(node) ? cache.get(node) : createDOMStyler(node, props);
1958 };
1959 function index(nodeOrSelector, props) {
1960 var node = typeof nodeOrSelector === 'string' ? document.querySelector(nodeOrSelector) : nodeOrSelector;
1961 return getStyler(node, props);
1962 }
1963
1964 /**
1965 * Creates a constant value over the lifecycle of a component.
1966 *
1967 * Even if `useMemo` is provided an empty array as its final argument, it doesn't offer
1968 * a guarantee that it won't re-run for performance reasons later on. By using `useConstant`
1969 * you can ensure that initialisers don't execute twice or more.
1970 */
1971 function useConstant(init) {
1972 var ref = React.useRef(null);
1973 if (ref.current === null) {
1974 ref.current = init();
1975 }
1976 return ref.current;
1977 }
1978
1979 var isMotionValue = function (value) {
1980 return value instanceof MotionValue;
1981 };
1982
1983 // Creating a styler factory for the `onUpdate` prop allows all values
1984 // to fire and the `onUpdate` prop will only fire once per frame
1985 var updateStyler = createStyler({
1986 onRead: function () { return null; },
1987 onRender: function (state, _a) {
1988 var onUpdate = _a.onUpdate;
1989 return onUpdate(state);
1990 },
1991 });
1992 var MotionValuesMap = /** @class */ (function () {
1993 function MotionValuesMap() {
1994 this.hasMounted = false;
1995 this.values = new Map();
1996 this.unsubscribers = new Map();
1997 }
1998 MotionValuesMap.prototype.has = function (key) {
1999 return this.values.has(key);
2000 };
2001 MotionValuesMap.prototype.set = function (key, value) {
2002 this.values.set(key, value);
2003 if (this.hasMounted) {
2004 this.bindValueToOutput(key, value);
2005 }
2006 };
2007 MotionValuesMap.prototype.get = function (key, defaultValue) {
2008 var value = this.values.get(key);
2009 if (value === undefined && defaultValue !== undefined) {
2010 value = new MotionValue(defaultValue);
2011 this.set(key, value);
2012 }
2013 return value;
2014 };
2015 MotionValuesMap.prototype.forEach = function (callback) {
2016 return this.values.forEach(callback);
2017 };
2018 MotionValuesMap.prototype.bindValueToOutput = function (key, value) {
2019 var _this = this;
2020 var onRender = function (v) { return _this.output && _this.output(key, v); };
2021 var unsubscribeOnRender = value.onRenderRequest(onRender);
2022 var onChange = function (v) {
2023 _this.onUpdate && _this.onUpdate.set(key, v);
2024 };
2025 var unsubscribeOnChange = value.onChange(onChange);
2026 if (this.unsubscribers.has(key)) {
2027 this.unsubscribers.get(key)();
2028 }
2029 this.unsubscribers.set(key, function () {
2030 unsubscribeOnRender();
2031 unsubscribeOnChange();
2032 });
2033 };
2034 MotionValuesMap.prototype.setOnUpdate = function (onUpdate) {
2035 this.onUpdate = undefined;
2036 if (onUpdate) {
2037 this.onUpdate = updateStyler({ onUpdate: onUpdate });
2038 }
2039 };
2040 MotionValuesMap.prototype.setTransformTemplate = function (transformTemplate) {
2041 if (this.transformTemplate !== transformTemplate) {
2042 this.transformTemplate = transformTemplate;
2043 this.updateTransformTemplate();
2044 }
2045 };
2046 MotionValuesMap.prototype.getTransformTemplate = function () {
2047 return this.transformTemplate;
2048 };
2049 MotionValuesMap.prototype.updateTransformTemplate = function () {
2050 if (this.output) {
2051 this.output("transform", this.transformTemplate);
2052 }
2053 };
2054 MotionValuesMap.prototype.mount = function (output) {
2055 var _this = this;
2056 this.hasMounted = true;
2057 if (output)
2058 this.output = output;
2059 this.values.forEach(function (value, key) { return _this.bindValueToOutput(key, value); });
2060 this.updateTransformTemplate();
2061 };
2062 MotionValuesMap.prototype.unmount = function () {
2063 var _this = this;
2064 this.values.forEach(function (_value, key) {
2065 var unsubscribe = _this.unsubscribers.get(key);
2066 unsubscribe && unsubscribe();
2067 });
2068 };
2069 return MotionValuesMap;
2070 }());
2071 var specialMotionValueProps = new Set(["dragOriginX", "dragOriginY"]);
2072 var useMotionValues = function (props) {
2073 var motionValues = useConstant(function () {
2074 var map = new MotionValuesMap();
2075 /**
2076 * Loop through every prop and add any detected `MotionValue`s. This is SVG-specific
2077 * code that should be extracted, perhaps considered hollistically with `useMotionStyles`.
2078 *
2079 * <motion.circle cx={motionValue(0)} />
2080 */
2081 for (var key in props) {
2082 if (isMotionValue(props[key]) &&
2083 !specialMotionValueProps.has(key)) {
2084 map.set(key, props[key]);
2085 }
2086 }
2087 return map;
2088 });
2089 motionValues.setOnUpdate(props.onUpdate);
2090 motionValues.setTransformTemplate(props.transformTemplate);
2091 return motionValues;
2092 };
2093
2094 var session = null;
2095 var syncRenderSession = {
2096 isOpen: function () { return session !== null; },
2097 open: function () {
2098 invariant(!session, "Sync render session already open");
2099 session = [];
2100 },
2101 flush: function () {
2102 invariant(session !== null, "No sync render session found");
2103 session && session.forEach(function (styler) { return styler.render(); });
2104 session = null;
2105 },
2106 push: function (styler) {
2107 invariant(session !== null, "No sync render session found");
2108 session && session.push(styler);
2109 },
2110 };
2111
2112 /**
2113 * `useEffect` gets resolved bottom-up. We defer some optional functionality to child
2114 * components, so to ensure everything runs correctly we export the ref-binding logic
2115 * to a new component rather than in `useMotionValues`.
2116 */
2117 var MountComponent = function (_a) {
2118 var ref = _a.innerRef, values = _a.values, isStatic = _a.isStatic;
2119 React.useEffect(function () {
2120 invariant(ref.current instanceof Element, "No `ref` found. Ensure components created with `motion.custom` forward refs using `React.forwardRef`");
2121 var domStyler = index(ref.current, {
2122 preparseOutput: false,
2123 enableHardwareAcceleration: !isStatic,
2124 });
2125 values.mount(function (key, value) {
2126 domStyler.set(key, value);
2127 if (syncRenderSession.isOpen()) {
2128 syncRenderSession.push(domStyler);
2129 }
2130 });
2131 return function () { return values.unmount(); };
2132 }, []);
2133 return null;
2134 };
2135 var Mount = React.memo(MountComponent);
2136
2137 var createValueResolver = function (resolver) { return function (values) {
2138 var resolvedValues = {};
2139 values.forEach(function (value, key) { return (resolvedValues[key] = resolver(value)); });
2140 return resolvedValues;
2141 }; };
2142 var resolveCurrent = createValueResolver(function (value) { return value.get(); });
2143
2144 var transformOriginProps$1 = new Set(["originX", "originY", "originZ"]);
2145 var isTransformOriginProp$1 = function (key) { return transformOriginProps$1.has(key); };
2146 var buildStyleAttr = function (values, styleProp, isStatic) {
2147 var motionValueStyles = resolveCurrent(values);
2148 var transformTemplate = values.getTransformTemplate();
2149 if (transformTemplate) {
2150 // If `transform` has been manually set as a string, pass that through the template
2151 // otherwise pass it forward to Stylefire's style property builder
2152 motionValueStyles.transform = styleProp.transform
2153 ? transformTemplate({}, styleProp.transform)
2154 : transformTemplate;
2155 }
2156 return buildStyleProperty(__assign(__assign({}, styleProp), motionValueStyles), !isStatic);
2157 };
2158 var useMotionStyles = function (values, styleProp, isStatic, transformValues) {
2159 if (styleProp === void 0) { styleProp = {}; }
2160 var style = {};
2161 var prevMotionStyles = React.useRef({}).current;
2162 for (var key in styleProp) {
2163 var thisStyle = styleProp[key];
2164 if (isMotionValue(thisStyle)) {
2165 // If this is a motion value, add it to our MotionValuesMap
2166 values.set(key, thisStyle);
2167 }
2168 else if (!isStatic &&
2169 (isTransformProp(key) || isTransformOriginProp$1(key))) {
2170 // Or if it's a transform prop, create a motion value (or update an existing one)
2171 // to ensure Stylefire can reconcile all the transform values together.
2172 // A further iteration on this would be to create a single styler per component that gets
2173 // used in the DOM renderer's buildStyleAttr *and* animations, then we would only
2174 // have to convert animating values to `MotionValues` (we could probably remove this entire function).
2175 // The only architectural consideration is to allow Stylefire to have elements mounted after
2176 // a styler is created.
2177 if (!values.has(key)) {
2178 // If it doesn't exist as a motion value, create it
2179 values.set(key, motionValue(thisStyle));
2180 }
2181 else {
2182 // Otherwise only update it if it's changed from a previous render
2183 if (thisStyle !== prevMotionStyles[key]) {
2184 var value = values.get(key);
2185 value.set(thisStyle);
2186 }
2187 }
2188 prevMotionStyles[key] = thisStyle;
2189 }
2190 else {
2191 style[key] = thisStyle;
2192 }
2193 }
2194 return transformValues ? transformValues(style) : style;
2195 };
2196
2197 var isKeyframesTarget = function (v) {
2198 return Array.isArray(v);
2199 };
2200
2201 var isCustomValue = function (v) {
2202 return Boolean(v && typeof v === "object" && v.mix && v.toValue);
2203 };
2204 var resolveFinalValueInKeyframes = function (v) {
2205 // TODO maybe throw if v.length - 1 is placeholder token?
2206 return isKeyframesTarget(v) ? v[v.length - 1] || 0 : v;
2207 };
2208
2209 var auto = {
2210 test: function (v) { return v === "auto"; },
2211 parse: function (v) { return v; },
2212 };
2213 var dimensionTypes = [number, px, percent, degrees, vw, vh, auto];
2214 var valueTypes$1 = __spreadArrays(dimensionTypes, [color, complex]);
2215 var testValueType = function (v) { return function (type) { return type.test(v); }; };
2216 var getDimensionValueType = function (v) {
2217 return dimensionTypes.find(testValueType(v));
2218 };
2219 var getValueType$1 = function (v) { return valueTypes$1.find(testValueType(v)); };
2220
2221 var Observer = /*#__PURE__*/function () {
2222 function Observer(_a, observer) {
2223 var _this = this;
2224 var middleware = _a.middleware,
2225 onComplete = _a.onComplete;
2226 this.isActive = true;
2227 this.update = function (v) {
2228 if (_this.observer.update) _this.updateObserver(v);
2229 };
2230 this.complete = function () {
2231 if (_this.observer.complete && _this.isActive) _this.observer.complete();
2232 if (_this.onComplete) _this.onComplete();
2233 _this.isActive = false;
2234 };
2235 this.error = function (err) {
2236 if (_this.observer.error && _this.isActive) _this.observer.error(err);
2237 _this.isActive = false;
2238 };
2239 this.observer = observer;
2240 this.updateObserver = function (v) {
2241 return observer.update(v);
2242 };
2243 this.onComplete = onComplete;
2244 if (observer.update && middleware && middleware.length) {
2245 middleware.forEach(function (m) {
2246 return _this.updateObserver = m(_this.updateObserver, _this.complete);
2247 });
2248 }
2249 }
2250 return Observer;
2251 }();
2252 var createObserver = function (observerCandidate, _a, onComplete) {
2253 var middleware = _a.middleware;
2254 if (typeof observerCandidate === 'function') {
2255 return new Observer({ middleware: middleware, onComplete: onComplete }, { update: observerCandidate });
2256 } else {
2257 return new Observer({ middleware: middleware, onComplete: onComplete }, observerCandidate);
2258 }
2259 };
2260
2261 var Action = /*#__PURE__*/function () {
2262 function Action(props) {
2263 if (props === void 0) {
2264 props = {};
2265 }
2266 this.props = props;
2267 }
2268 Action.prototype.create = function (props) {
2269 return new Action(props);
2270 };
2271 Action.prototype.start = function (observerCandidate) {
2272 if (observerCandidate === void 0) {
2273 observerCandidate = {};
2274 }
2275 var isComplete = false;
2276 var subscription = {
2277 stop: function () {
2278 return undefined;
2279 }
2280 };
2281 var _a = this.props,
2282 init = _a.init,
2283 observerProps = __rest(_a, ["init"]);
2284 var observer = createObserver(observerCandidate, observerProps, function () {
2285 isComplete = true;
2286 subscription.stop();
2287 });
2288 var api = init(observer);
2289 subscription = api ? __assign({}, subscription, api) : subscription;
2290 if (isComplete) subscription.stop();
2291 return subscription;
2292 };
2293 Action.prototype.applyMiddleware = function (middleware) {
2294 return this.create(__assign({}, this.props, { middleware: this.props.middleware ? [middleware].concat(this.props.middleware) : [middleware] }));
2295 };
2296 Action.prototype.pipe = function () {
2297 var funcs = [];
2298 for (var _i = 0; _i < arguments.length; _i++) {
2299 funcs[_i] = arguments[_i];
2300 }
2301 var pipedUpdate = funcs.length === 1 ? funcs[0] : pipe.apply(void 0, funcs);
2302 return this.applyMiddleware(function (update) {
2303 return function (v) {
2304 return update(pipedUpdate(v));
2305 };
2306 });
2307 };
2308 return Action;
2309 }();
2310 var action = function (init) {
2311 return new Action({ init: init });
2312 };
2313
2314 var createVectorTests = function (typeTests) {
2315 var testNames = Object.keys(typeTests);
2316 var isVectorProp = function (prop, key) {
2317 return prop !== undefined && !typeTests[key](prop);
2318 };
2319 var getVectorKeys = function (props) {
2320 return testNames.reduce(function (vectorKeys, key) {
2321 if (isVectorProp(props[key], key)) vectorKeys.push(key);
2322 return vectorKeys;
2323 }, []);
2324 };
2325 var testVectorProps = function (props) {
2326 return props && testNames.some(function (key) {
2327 return isVectorProp(props[key], key);
2328 });
2329 };
2330 return { getVectorKeys: getVectorKeys, testVectorProps: testVectorProps };
2331 };
2332 var unitTypes = [px, percent, degrees, vh, vw];
2333 var findUnitType = function (prop) {
2334 return unitTypes.find(function (type) {
2335 return type.test(prop);
2336 });
2337 };
2338 var isUnitProp = function (prop) {
2339 return Boolean(findUnitType(prop));
2340 };
2341 var createAction = function (action, props) {
2342 return action(props);
2343 };
2344 var createUnitAction = function (action, _a) {
2345 var from = _a.from,
2346 to = _a.to,
2347 props = __rest(_a, ["from", "to"]);
2348 var unitType = findUnitType(from) || findUnitType(to);
2349 var transform = unitType.transform,
2350 parse = unitType.parse;
2351 return action(__assign({}, props, { from: typeof from === 'string' ? parse(from) : from, to: typeof to === 'string' ? parse(to) : to })).pipe(transform);
2352 };
2353 var createMixerAction = function (mixer) {
2354 return function (action, _a) {
2355 var from = _a.from,
2356 to = _a.to,
2357 props = __rest(_a, ["from", "to"]);
2358 return action(__assign({}, props, { from: 0, to: 1 })).pipe(mixer(from, to));
2359 };
2360 };
2361 var createColorAction = /*#__PURE__*/createMixerAction(mixColor);
2362 var createComplexAction = /*#__PURE__*/createMixerAction(mixComplex);
2363 var createVectorAction = function (action, typeTests) {
2364 var _a = createVectorTests(typeTests),
2365 testVectorProps = _a.testVectorProps,
2366 getVectorKeys = _a.getVectorKeys;
2367 var vectorAction = function (props) {
2368 var isVector = testVectorProps(props);
2369 if (!isVector) return action(props);
2370 var vectorKeys = getVectorKeys(props);
2371 var testKey = vectorKeys[0];
2372 var testProp = props[testKey];
2373 return getActionCreator(testProp)(action, props, vectorKeys);
2374 };
2375 return vectorAction;
2376 };
2377 var getActionCreator = function (prop) {
2378 if (typeof prop === 'number') {
2379 return createAction;
2380 } else if (isUnitProp(prop)) {
2381 return createUnitAction;
2382 } else if (color.test(prop)) {
2383 return createColorAction;
2384 } else if (complex.test(prop)) {
2385 return createComplexAction;
2386 } else {
2387 return createAction;
2388 }
2389 };
2390
2391 var decay = function (props) {
2392 if (props === void 0) {
2393 props = {};
2394 }
2395 return action(function (_a) {
2396 var complete = _a.complete,
2397 update = _a.update;
2398 var _b = props.velocity,
2399 velocity = _b === void 0 ? 0 : _b,
2400 _c = props.from,
2401 from = _c === void 0 ? 0 : _c,
2402 _d = props.power,
2403 power = _d === void 0 ? 0.8 : _d,
2404 _e = props.timeConstant,
2405 timeConstant = _e === void 0 ? 350 : _e,
2406 _f = props.restDelta,
2407 restDelta = _f === void 0 ? 0.5 : _f,
2408 modifyTarget = props.modifyTarget;
2409 var elapsed = 0;
2410 var amplitude = power * velocity;
2411 var idealTarget = Math.round(from + amplitude);
2412 var target = typeof modifyTarget === 'undefined' ? idealTarget : modifyTarget(idealTarget);
2413 var process = sync.update(function (_a) {
2414 var frameDelta = _a.delta;
2415 elapsed += frameDelta;
2416 var delta = -amplitude * Math.exp(-elapsed / timeConstant);
2417 var isMoving = delta > restDelta || delta < -restDelta;
2418 var current = isMoving ? target + delta : target;
2419 update(current);
2420 if (!isMoving) {
2421 cancelSync.update(process);
2422 complete();
2423 }
2424 }, true);
2425 return {
2426 stop: function () {
2427 return cancelSync.update(process);
2428 }
2429 };
2430 });
2431 };
2432 var vectorDecay = /*#__PURE__*/createVectorAction(decay, {
2433 from: number.test,
2434 modifyTarget: function (func) {
2435 return typeof func === 'function';
2436 },
2437 velocity: number.test
2438 });
2439
2440 var spring = function (props) {
2441 if (props === void 0) {
2442 props = {};
2443 }
2444 return action(function (_a) {
2445 var update = _a.update,
2446 complete = _a.complete;
2447 var _b = props.velocity,
2448 velocity = _b === void 0 ? 0.0 : _b;
2449 var _c = props.from,
2450 from = _c === void 0 ? 0.0 : _c,
2451 _d = props.to,
2452 to = _d === void 0 ? 0.0 : _d,
2453 _e = props.stiffness,
2454 stiffness = _e === void 0 ? 100 : _e,
2455 _f = props.damping,
2456 damping = _f === void 0 ? 10 : _f,
2457 _g = props.mass,
2458 mass = _g === void 0 ? 1.0 : _g,
2459 _h = props.restSpeed,
2460 restSpeed = _h === void 0 ? 0.01 : _h,
2461 _j = props.restDelta,
2462 restDelta = _j === void 0 ? 0.01 : _j;
2463 var initialVelocity = velocity ? -(velocity / 1000) : 0.0;
2464 var t = 0;
2465 var delta = to - from;
2466 var position = from;
2467 var prevPosition = position;
2468 var process = sync.update(function (_a) {
2469 var timeDelta = _a.delta;
2470 t += timeDelta;
2471 var dampingRatio = damping / (2 * Math.sqrt(stiffness * mass));
2472 var angularFreq = Math.sqrt(stiffness / mass) / 1000;
2473 prevPosition = position;
2474 if (dampingRatio < 1) {
2475 var envelope = Math.exp(-dampingRatio * angularFreq * t);
2476 var expoDecay = angularFreq * Math.sqrt(1.0 - dampingRatio * dampingRatio);
2477 position = to - envelope * ((initialVelocity + dampingRatio * angularFreq * delta) / expoDecay * Math.sin(expoDecay * t) + delta * Math.cos(expoDecay * t));
2478 } else {
2479 var envelope = Math.exp(-angularFreq * t);
2480 position = to - envelope * (delta + (initialVelocity + angularFreq * delta) * t);
2481 }
2482 velocity = velocityPerSecond(position - prevPosition, timeDelta);
2483 var isBelowVelocityThreshold = Math.abs(velocity) <= restSpeed;
2484 var isBelowDisplacementThreshold = Math.abs(to - position) <= restDelta;
2485 if (isBelowVelocityThreshold && isBelowDisplacementThreshold) {
2486 position = to;
2487 update(position);
2488 cancelSync.update(process);
2489 complete();
2490 } else {
2491 update(position);
2492 }
2493 }, true);
2494 return {
2495 stop: function () {
2496 return cancelSync.update(process);
2497 }
2498 };
2499 });
2500 };
2501 var vectorSpring = /*#__PURE__*/createVectorAction(spring, {
2502 from: number.test,
2503 to: number.test,
2504 stiffness: number.test,
2505 damping: number.test,
2506 mass: number.test,
2507 velocity: number.test
2508 });
2509
2510 var inertia = function (_a) {
2511 var _b = _a.from,
2512 from = _b === void 0 ? 0 : _b,
2513 _c = _a.velocity,
2514 velocity = _c === void 0 ? 0 : _c,
2515 min = _a.min,
2516 max = _a.max,
2517 _d = _a.power,
2518 power = _d === void 0 ? 0.8 : _d,
2519 _e = _a.timeConstant,
2520 timeConstant = _e === void 0 ? 700 : _e,
2521 _f = _a.bounceStiffness,
2522 bounceStiffness = _f === void 0 ? 500 : _f,
2523 _g = _a.bounceDamping,
2524 bounceDamping = _g === void 0 ? 10 : _g,
2525 _h = _a.restDelta,
2526 restDelta = _h === void 0 ? 1 : _h,
2527 modifyTarget = _a.modifyTarget;
2528 return action(function (_a) {
2529 var update = _a.update,
2530 complete = _a.complete;
2531 var prev = from;
2532 var current = from;
2533 var activeAnimation;
2534 var isSpring = false;
2535 var isLessThanMin = function (v) {
2536 return min !== undefined && v <= min;
2537 };
2538 var isMoreThanMax = function (v) {
2539 return max !== undefined && v >= max;
2540 };
2541 var isOutOfBounds = function (v) {
2542 return isLessThanMin(v) || isMoreThanMax(v);
2543 };
2544 var isTravellingAwayFromBounds = function (v, currentVelocity) {
2545 return isLessThanMin(v) && currentVelocity < 0 || isMoreThanMax(v) && currentVelocity > 0;
2546 };
2547 var onUpdate = function (v) {
2548 update(v);
2549 prev = current;
2550 current = v;
2551 velocity = velocityPerSecond(current - prev, getFrameData().delta);
2552 if (activeAnimation && !isSpring && isTravellingAwayFromBounds(v, velocity)) {
2553 startSpring({ from: v, velocity: velocity });
2554 }
2555 };
2556 var startAnimation = function (animation, next) {
2557 activeAnimation && activeAnimation.stop();
2558 activeAnimation = animation.start({
2559 update: onUpdate,
2560 complete: function () {
2561 if (next) {
2562 next();
2563 return;
2564 }
2565 complete();
2566 }
2567 });
2568 };
2569 var startSpring = function (props) {
2570 isSpring = true;
2571 startAnimation(vectorSpring(__assign({}, props, { to: isLessThanMin(props.from) ? min : max, stiffness: bounceStiffness, damping: bounceDamping, restDelta: restDelta })));
2572 };
2573 if (isOutOfBounds(from)) {
2574 startSpring({ from: from, velocity: velocity });
2575 } else if (velocity !== 0) {
2576 var animation = vectorDecay({
2577 from: from,
2578 velocity: velocity,
2579 timeConstant: timeConstant,
2580 power: power,
2581 restDelta: isOutOfBounds(from) ? 20 : restDelta,
2582 modifyTarget: modifyTarget
2583 });
2584 startAnimation(animation, function () {
2585 if (isOutOfBounds(current)) {
2586 startSpring({ from: current, velocity: velocity });
2587 } else {
2588 complete();
2589 }
2590 });
2591 } else {
2592 complete();
2593 }
2594 return {
2595 stop: function () {
2596 return activeAnimation && activeAnimation.stop();
2597 }
2598 };
2599 });
2600 };
2601 var index$1 = /*#__PURE__*/createVectorAction(inertia, {
2602 from: number.test,
2603 velocity: number.test,
2604 min: number.test,
2605 max: number.test,
2606 damping: number.test,
2607 stiffness: number.test,
2608 modifyTarget: function (func) {
2609 return typeof func === 'function';
2610 }
2611 });
2612
2613 var scrubber = function (_a) {
2614 var _b = _a.from,
2615 from = _b === void 0 ? 0 : _b,
2616 _c = _a.to,
2617 to = _c === void 0 ? 1 : _c,
2618 _d = _a.ease,
2619 ease = _d === void 0 ? linear : _d,
2620 _e = _a.reverseEase,
2621 reverseEase = _e === void 0 ? false : _e;
2622 if (reverseEase) {
2623 ease = createReversedEasing(ease);
2624 }
2625 return action(function (_a) {
2626 var update = _a.update;
2627 return {
2628 seek: function (progress) {
2629 return update(progress);
2630 }
2631 };
2632 }).pipe(ease, function (v) {
2633 return mix(from, to, v);
2634 });
2635 };
2636 var vectorScrubber = /*#__PURE__*/createVectorAction(scrubber, {
2637 ease: function (func) {
2638 return typeof func === 'function';
2639 },
2640 from: number.test,
2641 to: number.test
2642 });
2643
2644 var clampProgress$1 = /*#__PURE__*/clamp$1$1(0, 1);
2645 var tween = function (props) {
2646 if (props === void 0) {
2647 props = {};
2648 }
2649 return action(function (_a) {
2650 var update = _a.update,
2651 complete = _a.complete;
2652 var _b = props.duration,
2653 duration = _b === void 0 ? 300 : _b,
2654 _c = props.ease,
2655 ease = _c === void 0 ? easeOut : _c,
2656 _d = props.flip,
2657 flip = _d === void 0 ? 0 : _d,
2658 _e = props.loop,
2659 loop = _e === void 0 ? 0 : _e,
2660 _f = props.yoyo,
2661 yoyo = _f === void 0 ? 0 : _f,
2662 _g = props.repeatDelay,
2663 repeatDelay = _g === void 0 ? 0 : _g;
2664 var _h = props.from,
2665 from = _h === void 0 ? 0 : _h,
2666 _j = props.to,
2667 to = _j === void 0 ? 1 : _j,
2668 _k = props.elapsed,
2669 elapsed = _k === void 0 ? 0 : _k,
2670 _l = props.flipCount,
2671 flipCount = _l === void 0 ? 0 : _l,
2672 _m = props.yoyoCount,
2673 yoyoCount = _m === void 0 ? 0 : _m,
2674 _o = props.loopCount,
2675 loopCount = _o === void 0 ? 0 : _o;
2676 var playhead = vectorScrubber({ from: from, to: to, ease: ease }).start(update);
2677 var currentProgress = 0;
2678 var process;
2679 var isActive = false;
2680 var reverseAnimation = function (reverseEase) {
2681 var _a;
2682 if (reverseEase === void 0) {
2683 reverseEase = false;
2684 }
2685 _a = [to, from], from = _a[0], to = _a[1];
2686 playhead = vectorScrubber({ from: from, to: to, ease: ease, reverseEase: reverseEase }).start(update);
2687 };
2688 var isTweenComplete = function () {
2689 var isComplete = isActive && elapsed > duration + repeatDelay;
2690 if (!isComplete) return false;
2691 if (isComplete && !loop && !flip && !yoyo) return true;
2692 var overtime = elapsed - duration;
2693 elapsed = overtime - repeatDelay;
2694 if (loop && loopCount < loop) {
2695 loopCount++;
2696 return false;
2697 } else if (flip && flipCount < flip) {
2698 flipCount++;
2699 reverseAnimation();
2700 return false;
2701 } else if (yoyo && yoyoCount < yoyo) {
2702 yoyoCount++;
2703 reverseAnimation(yoyoCount % 2 !== 0);
2704 return false;
2705 }
2706 return true;
2707 };
2708 var updateTween = function () {
2709 currentProgress = clampProgress$1(progress(0, duration, elapsed));
2710 playhead.seek(currentProgress);
2711 };
2712 var startTimer = function () {
2713 isActive = true;
2714 process = sync.update(function (_a) {
2715 var delta = _a.delta;
2716 elapsed += delta;
2717 updateTween();
2718 if (isTweenComplete()) {
2719 cancelSync.update(process);
2720 complete && sync.update(complete, false, true);
2721 }
2722 }, true);
2723 };
2724 var stopTimer = function () {
2725 isActive = false;
2726 if (process) cancelSync.update(process);
2727 };
2728 startTimer();
2729 return {
2730 isActive: function () {
2731 return isActive;
2732 },
2733 getElapsed: function () {
2734 return clamp$1$1(0, duration, elapsed);
2735 },
2736 getProgress: function () {
2737 return currentProgress;
2738 },
2739 stop: function () {
2740 stopTimer();
2741 },
2742 pause: function () {
2743 stopTimer();
2744 return this;
2745 },
2746 resume: function () {
2747 if (!isActive) startTimer();
2748 return this;
2749 },
2750 seek: function (newProgress) {
2751 elapsed = mix(0, duration, newProgress);
2752 sync.update(updateTween, false, true);
2753 return this;
2754 },
2755 reverse: function () {
2756 reverseAnimation();
2757 return this;
2758 }
2759 };
2760 });
2761 };
2762
2763 var clampProgress$1$1 = /*#__PURE__*/clamp$1$1(0, 1);
2764 var defaultEasings = function (values, easing) {
2765 return values.map(function () {
2766 return easing || easeOut;
2767 }).splice(0, values.length - 1);
2768 };
2769 var defaultTimings = function (values) {
2770 var numValues = values.length;
2771 return values.map(function (value, i) {
2772 return i !== 0 ? i / (numValues - 1) : 0;
2773 });
2774 };
2775 var interpolateScrubbers = function (input, scrubbers, update) {
2776 var rangeLength = input.length;
2777 var finalInputIndex = rangeLength - 1;
2778 var finalScrubberIndex = finalInputIndex - 1;
2779 var subs = scrubbers.map(function (scrub) {
2780 return scrub.start(update);
2781 });
2782 return function (v) {
2783 if (v <= input[0]) {
2784 subs[0].seek(0);
2785 }
2786 if (v >= input[finalInputIndex]) {
2787 subs[finalScrubberIndex].seek(1);
2788 }
2789 var i = 1;
2790 for (; i < rangeLength; i++) {
2791 if (input[i] > v || i === finalInputIndex) break;
2792 }
2793 var progressInRange = progress(input[i - 1], input[i], v);
2794 subs[i - 1].seek(clampProgress$1$1(progressInRange));
2795 };
2796 };
2797 var keyframes = function (_a) {
2798 var easings = _a.easings,
2799 _b = _a.ease,
2800 ease = _b === void 0 ? linear : _b,
2801 times = _a.times,
2802 values = _a.values,
2803 tweenProps = __rest(_a, ["easings", "ease", "times", "values"]);
2804 easings = Array.isArray(easings) ? easings : defaultEasings(values, easings);
2805 times = times || defaultTimings(values);
2806 var scrubbers = easings.map(function (easing, i) {
2807 return vectorScrubber({
2808 from: values[i],
2809 to: values[i + 1],
2810 ease: easing
2811 });
2812 });
2813 return tween(__assign({}, tweenProps, { ease: ease })).applyMiddleware(function (update) {
2814 return interpolateScrubbers(times, scrubbers, update);
2815 });
2816 };
2817
2818 var listen = function (element, events, options) {
2819 return action(function (_a) {
2820 var update = _a.update;
2821 var eventNames = events.split(' ').map(function (eventName) {
2822 element.addEventListener(eventName, update, options);
2823 return eventName;
2824 });
2825 return {
2826 stop: function () {
2827 return eventNames.forEach(function (eventName) {
2828 return element.removeEventListener(eventName, update, options);
2829 });
2830 }
2831 };
2832 });
2833 };
2834
2835 var defaultPointerPos = function () {
2836 return {
2837 clientX: 0,
2838 clientY: 0,
2839 pageX: 0,
2840 pageY: 0,
2841 x: 0,
2842 y: 0
2843 };
2844 };
2845 var eventToPoint = function (e, point) {
2846 if (point === void 0) {
2847 point = defaultPointerPos();
2848 }
2849 point.clientX = point.x = e.clientX;
2850 point.clientY = point.y = e.clientY;
2851 point.pageX = e.pageX;
2852 point.pageY = e.pageY;
2853 return point;
2854 };
2855
2856 var points = [/*#__PURE__*/defaultPointerPos()];
2857 if (typeof document !== 'undefined') {
2858 var updatePointsLocation = function (_a) {
2859 var touches = _a.touches;
2860 var numTouches = touches.length;
2861 points.length = 0;
2862 for (var i = 0; i < numTouches; i++) {
2863 var thisTouch = touches[i];
2864 points.push(eventToPoint(thisTouch));
2865 }
2866 };
2867 listen(document, 'touchstart touchmove', {
2868 passive: true,
2869 capture: true
2870 }).start(updatePointsLocation);
2871 }
2872
2873 var point = /*#__PURE__*/defaultPointerPos();
2874 if (typeof document !== 'undefined') {
2875 var updatePointLocation = function (e) {
2876 eventToPoint(e, point);
2877 };
2878 listen(document, 'mousedown mousemove', true).start(updatePointLocation);
2879 }
2880
2881 var delay = function (timeToDelay) {
2882 return action(function (_a) {
2883 var complete = _a.complete;
2884 var timeout = setTimeout(complete, timeToDelay);
2885 return {
2886 stop: function () {
2887 return clearTimeout(timeout);
2888 }
2889 };
2890 });
2891 };
2892
2893 var underDampedSpring = function () { return ({
2894 type: "spring",
2895 stiffness: 500,
2896 damping: 25,
2897 restDelta: 0.5,
2898 restSpeed: 10,
2899 }); };
2900 var overDampedSpring = function (to) { return ({
2901 type: "spring",
2902 stiffness: 700,
2903 damping: to === 0 ? 100 : 35,
2904 }); };
2905 var linearTween = function () { return ({
2906 ease: "linear",
2907 duration: 0.3,
2908 }); };
2909 var keyframes$1 = function (values) { return ({
2910 type: "keyframes",
2911 duration: 0.8,
2912 values: values,
2913 }); };
2914 var defaultTransitions = {
2915 x: underDampedSpring,
2916 y: underDampedSpring,
2917 z: underDampedSpring,
2918 rotate: underDampedSpring,
2919 rotateX: underDampedSpring,
2920 rotateY: underDampedSpring,
2921 rotateZ: underDampedSpring,
2922 scaleX: overDampedSpring,
2923 scaleY: overDampedSpring,
2924 scale: overDampedSpring,
2925 opacity: linearTween,
2926 backgroundColor: linearTween,
2927 color: linearTween,
2928 default: overDampedSpring,
2929 };
2930 var getDefaultTransition = function (valueKey, to) {
2931 var transitionFactory;
2932 if (isKeyframesTarget(to)) {
2933 transitionFactory = keyframes$1;
2934 }
2935 else {
2936 transitionFactory =
2937 defaultTransitions[valueKey] || defaultTransitions.default;
2938 }
2939 return __assign({ to: to }, transitionFactory(to));
2940 };
2941
2942 /**
2943 * A Popmotion action that accepts a single `to` prop. When it starts, it immediately
2944 * updates with `to` and then completes. By using this we can compose instant transitions
2945 * in with the same logic that applies `delay` or returns a `Promise` etc.
2946 *
2947 * Accepting `duration` is a little bit of a hack that simply defers the completetion of
2948 * the animation until after the duration finishes. This is for situations when you're **only**
2949 * animating non-animatable values and then setting something on `transitionEnd`. Really
2950 * you want this to fire after the "animation" finishes, rather than instantly.
2951 *
2952 * ```
2953 * animate={{
2954 * display: 'block',
2955 * transitionEnd: { display: 'none' }
2956 * }}
2957 * ```
2958 */
2959 var just = function (_a) {
2960 var to = _a.to, duration = _a.duration;
2961 return action(function (_a) {
2962 var update = _a.update, complete = _a.complete;
2963 update(to);
2964 duration ? delay(duration).start({ complete: complete }) : complete();
2965 });
2966 };
2967
2968 var easingDefinitionToFunction = function (definition) {
2969 if (Array.isArray(definition)) {
2970 // If cubic bezier definition, create bezier curve
2971 invariant(definition.length === 4, "Cubic bezier arrays must contain four numerical values.");
2972 var x1 = definition[0], y1 = definition[1], x2 = definition[2], y2 = definition[3];
2973 return cubicBezier(x1, y1, x2, y2);
2974 }
2975 else if (typeof definition === "string") {
2976 // Else lookup from table
2977 invariant(easingLookup[definition] !== undefined, "Invalid easing type '" + definition + "'");
2978 return easingLookup[definition];
2979 }
2980 return definition;
2981 };
2982 var isEasingArray = function (ease) {
2983 return Array.isArray(ease) && typeof ease[0] !== "number";
2984 };
2985
2986 var isDurationAnimation = function (v) {
2987 return v.hasOwnProperty("duration") || v.hasOwnProperty("repeatDelay");
2988 };
2989
2990 /**
2991 * Check if a value is animatable. Examples:
2992 *
2993 * ✅: 100, "100px", "#fff"
2994 * ❌: "block", "url(2.jpg)"
2995 * @param value
2996 *
2997 * @internal
2998 */
2999 var isAnimatable = function (key, value) {
3000 // If the list of keys tat might be non-animatable grows, replace with Set
3001 if (key === "zIndex")
3002 return false;
3003 // If it's a number or a keyframes array, we can animate it. We might at some point
3004 // need to do a deep isAnimatable check of keyframes, or let Popmotion handle this,
3005 // but for now lets leave it like this for performance reasons
3006 if (typeof value === "number" || Array.isArray(value))
3007 return true;
3008 if (typeof value === "string" && // It's animatable if we have a string
3009 complex.test(value) && // And it contains numbers and/or colors
3010 !value.startsWith("url(") // Unless it starts with "url("
3011 ) {
3012 return true;
3013 }
3014 return false;
3015 };
3016
3017 /**
3018 * Converts seconds to milliseconds
3019 *
3020 * @param seconds - Time in seconds.
3021 * @return milliseconds - Converted time in milliseconds.
3022 */
3023 var secondsToMilliseconds = function (seconds) { return seconds * 1000; };
3024
3025 var transitions = { tween: tween, spring: vectorSpring, keyframes: keyframes, inertia: index$1, just: just };
3026 var transitionOptionParser = {
3027 tween: function (opts) {
3028 if (opts.ease) {
3029 var ease = isEasingArray(opts.ease) ? opts.ease[0] : opts.ease;
3030 opts.ease = easingDefinitionToFunction(ease);
3031 }
3032 return opts;
3033 },
3034 keyframes: function (_a) {
3035 var from = _a.from, to = _a.to, velocity = _a.velocity, opts = __rest(_a, ["from", "to", "velocity"]);
3036 if (opts.values && opts.values[0] === null) {
3037 var values = __spreadArrays(opts.values);
3038 values[0] = from;
3039 opts.values = values;
3040 }
3041 if (opts.ease) {
3042 opts.easings = isEasingArray(opts.ease)
3043 ? opts.ease.map(easingDefinitionToFunction)
3044 : easingDefinitionToFunction(opts.ease);
3045 }
3046 opts.ease = linear;
3047 return opts;
3048 },
3049 };
3050 var isTransitionDefined = function (_a) {
3051 var when = _a.when, delay = _a.delay, delayChildren = _a.delayChildren, staggerChildren = _a.staggerChildren, staggerDirection = _a.staggerDirection, transition = __rest(_a, ["when", "delay", "delayChildren", "staggerChildren", "staggerDirection"]);
3052 return Object.keys(transition).length;
3053 };
3054 var getTransitionDefinition = function (key, to, transitionDefinition) {
3055 var delay = transitionDefinition ? transitionDefinition.delay : 0;
3056 // If no object, return default transition
3057 // A better way to handle this would be to deconstruct out all the shared Orchestration props
3058 // and see if there's any props remaining
3059 if (transitionDefinition === undefined ||
3060 !isTransitionDefined(transitionDefinition)) {
3061 return __assign({ delay: delay }, getDefaultTransition(key, to));
3062 }
3063 var valueTransitionDefinition = transitionDefinition[key] ||
3064 transitionDefinition.default ||
3065 transitionDefinition;
3066 if (valueTransitionDefinition.type === false) {
3067 return {
3068 delay: valueTransitionDefinition.hasOwnProperty("delay")
3069 ? valueTransitionDefinition.delay
3070 : delay,
3071 to: isKeyframesTarget(to)
3072 ? to[to.length - 1]
3073 : to,
3074 type: "just",
3075 };
3076 }
3077 else if (isKeyframesTarget(to)) {
3078 return __assign(__assign({ values: to, duration: 0.8, delay: delay, ease: "linear" }, valueTransitionDefinition), {
3079 // This animation must be keyframes if we're animating through an array
3080 type: "keyframes" });
3081 }
3082 else {
3083 return __assign({ type: "tween", to: to,
3084 delay: delay }, valueTransitionDefinition);
3085 }
3086 };
3087 var preprocessOptions = function (type, opts) {
3088 return transitionOptionParser[type]
3089 ? transitionOptionParser[type](opts)
3090 : opts;
3091 };
3092 var getAnimation = function (key, value, target, transition) {
3093 var origin = value.get();
3094 var isOriginAnimatable = isAnimatable(key, origin);
3095 var isTargetAnimatable = isAnimatable(key, target);
3096 // TODO we could probably improve this check to ensure both values are of the same type -
3097 // for instance 100 to #fff. This might live better in Popmotion.
3098 warning(isOriginAnimatable === isTargetAnimatable, "You are trying to animate " + key + " from \"" + origin + "\" to " + target + ". \"" + origin + "\" is not an animatable value - to enable this animation set " + origin + " to a value animatable to " + target + " via the `style` property.");
3099 // Parse the `transition` prop and return options for the Popmotion animation
3100 var _a = getTransitionDefinition(key, target, transition), _b = _a.type, type = _b === void 0 ? "tween" : _b, transitionDefinition = __rest(_a, ["type"]);
3101 // If this is an animatable pair of values, return an animation, otherwise use `just`
3102 var actionFactory = isOriginAnimatable && isTargetAnimatable
3103 ? transitions[type]
3104 : just;
3105 var opts = preprocessOptions(type, __assign({ from: origin, velocity: value.getVelocity() }, transitionDefinition));
3106 // Convert duration from Framer Motion's seconds into Popmotion's milliseconds
3107 if (isDurationAnimation(opts)) {
3108 if (opts.duration) {
3109 opts.duration = secondsToMilliseconds(opts.duration);
3110 }
3111 if (opts.repeatDelay) {
3112 opts.repeatDelay = secondsToMilliseconds(opts.repeatDelay);
3113 }
3114 }
3115 return [actionFactory, opts];
3116 };
3117 /**
3118 * Start animation on a value. This function completely encapsulates Popmotion-specific logic.
3119 *
3120 * @internal
3121 */
3122 function startAnimation(key, value, target, _a) {
3123 var _b = _a.delay, delay$1 = _b === void 0 ? 0 : _b, transition = __rest(_a, ["delay"]);
3124 return value.start(function (complete) {
3125 var activeAnimation;
3126 var _a = getAnimation(key, value, target, transition), animationFactory = _a[0], _b = _a[1], valueDelay = _b.delay, options = __rest(_b, ["delay"]);
3127 if (valueDelay !== undefined) {
3128 delay$1 = valueDelay;
3129 }
3130 var animate = function () {
3131 var animation = animationFactory(options);
3132 // Bind animation opts to animation
3133 activeAnimation = animation.start({
3134 update: function (v) { return value.set(v); },
3135 complete: complete,
3136 });
3137 };
3138 // If we're delaying this animation, only resolve it **after** the delay to
3139 // ensure the value's resolve velocity is up-to-date.
3140 if (delay$1) {
3141 activeAnimation = delay(secondsToMilliseconds(delay$1)).start({
3142 complete: animate,
3143 });
3144 }
3145 else {
3146 animate();
3147 }
3148 return function () {
3149 if (activeAnimation)
3150 activeAnimation.stop();
3151 };
3152 });
3153 }
3154
3155 /**
3156 * Get the current value of every `MotionValue`
3157 * @param values -
3158 */
3159 var getCurrent = function (values) {
3160 var current = {};
3161 values.forEach(function (value, key) { return (current[key] = value.get()); });
3162 return current;
3163 };
3164 /**
3165 * Get the current velocity of every `MotionValue`
3166 * @param values -
3167 */
3168 var getVelocity = function (values) {
3169 var velocity = {};
3170 values.forEach(function (value, key) { return (velocity[key] = value.getVelocity()); });
3171 return velocity;
3172 };
3173 /**
3174 * Check if value is a function that returns a `Target`. A generic typeof === 'function'
3175 * check, just helps with typing.
3176 * @param p -
3177 */
3178 var isTargetResolver = function (p) {
3179 return typeof p === "function";
3180 };
3181 /**
3182 * Check if value is a list of variant labels
3183 * @param v -
3184 */
3185 var isVariantLabels = function (v) { return Array.isArray(v); };
3186 /**
3187 * Check if value is a numerical string, ie "100" or "100px"
3188 */
3189 var isNumericalString = function (v) { return /^\d*\.?\d+$/.test(v); };
3190 /**
3191 * Control animations for a single component
3192 *
3193 * @internal
3194 */
3195 var ValueAnimationControls = /** @class */ (function () {
3196 function ValueAnimationControls(_a) {
3197 var _this = this;
3198 var values = _a.values, readValueFromSource = _a.readValueFromSource, makeTargetAnimatable = _a.makeTargetAnimatable;
3199 /**
3200 * A reference to the component's latest props. We could probably ditch this in
3201 * favour to a reference to the `custom` prop now we don't send all props through
3202 * to target resolvers.
3203 */
3204 this.props = {};
3205 /**
3206 * The component's variants, as provided by `variants`
3207 */
3208 this.variants = {};
3209 /**
3210 * A set of values that we animate back to when a value is cleared of all overrides.
3211 */
3212 this.baseTarget = {};
3213 /**
3214 * A series of target overrides that we can animate to/from when overrides are set/cleared.
3215 */
3216 this.overrides = [];
3217 /**
3218 * A series of target overrides as they were originally resolved.
3219 */
3220 this.resolvedOverrides = [];
3221 /**
3222 * A Set of currently active override indexes
3223 */
3224 this.activeOverrides = new Set();
3225 /**
3226 * A Set of value keys that are currently animating.
3227 */
3228 this.isAnimating = new Set();
3229 /**
3230 * Check if the associated `MotionValueMap` has a key with the provided string.
3231 * Pre-bound to the class so we can provide directly to the `filter` in `checkForNewValues`.
3232 */
3233 this.hasValue = function (key) { return !_this.values.has(key); };
3234 this.values = values;
3235 this.readValueFromSource = readValueFromSource;
3236 this.makeTargetAnimatable = makeTargetAnimatable;
3237 this.values.forEach(function (value, key) { return (_this.baseTarget[key] = value.get()); });
3238 }
3239 /**
3240 * Set the reference to the component's props.
3241 * @param props -
3242 */
3243 ValueAnimationControls.prototype.setProps = function (props) {
3244 this.props = props;
3245 };
3246 /**
3247 * Set the reference to the component's variants
3248 * @param variants -
3249 */
3250 ValueAnimationControls.prototype.setVariants = function (variants) {
3251 if (variants)
3252 this.variants = variants;
3253 };
3254 /**
3255 * Set the component's default transition
3256 * @param transition -
3257 */
3258 ValueAnimationControls.prototype.setDefaultTransition = function (transition) {
3259 if (transition)
3260 this.defaultTransition = transition;
3261 };
3262 /**
3263 * Set motion values without animation.
3264 *
3265 * @param definition -
3266 * @param isActive -
3267 */
3268 ValueAnimationControls.prototype.setValues = function (definition, _a) {
3269 var _this = this;
3270 var _b = _a === void 0 ? {} : _a, _c = _b.isActive, isActive = _c === void 0 ? new Set() : _c, priority = _b.priority;
3271 var _d = this.resolveVariant(definition), target = _d.target, transitionEnd = _d.transitionEnd;
3272 target = this.transformValues(__assign(__assign({}, target), transitionEnd));
3273 return Object.keys(target).forEach(function (key) {
3274 if (isActive.has(key))
3275 return;
3276 isActive.add(key);
3277 if (target) {
3278 var targetValue = resolveFinalValueInKeyframes(target[key]);
3279 if (_this.values.has(key)) {
3280 var value = _this.values.get(key);
3281 value && value.set(targetValue);
3282 }
3283 else {
3284 _this.values.set(key, motionValue(targetValue));
3285 }
3286 if (!priority)
3287 _this.baseTarget[key] = targetValue;
3288 }
3289 });
3290 };
3291 /**
3292 * Allows `transformValues` to be set by a component that allows us to
3293 * transform the values in a given `Target`. This allows Framer Library
3294 * to extend Framer Motion to animate `Color` variables etc. Currently we have
3295 * to manually support these extended types here in Framer Motion.
3296 *
3297 * @param values -
3298 */
3299 ValueAnimationControls.prototype.transformValues = function (values) {
3300 var transformValues = this.props.transformValues;
3301 return transformValues ? transformValues(values) : values;
3302 };
3303 /**
3304 * Check a `Target` for new values we haven't animated yet, and add them
3305 * to the `MotionValueMap`.
3306 *
3307 * Currently there's functionality here that is DOM-specific, we should allow
3308 * this functionality to be injected by the factory that creates DOM-specific
3309 * components.
3310 *
3311 * @param target -
3312 */
3313 ValueAnimationControls.prototype.checkForNewValues = function (target) {
3314 var newValueKeys = Object.keys(target).filter(this.hasValue);
3315 var numNewValues = newValueKeys.length;
3316 if (!numNewValues)
3317 return;
3318 for (var i = 0; i < numNewValues; i++) {
3319 var key = newValueKeys[i];
3320 var targetValue = target[key];
3321 var value = null;
3322 // If this is a keyframes value, we can attempt to use the first value in the
3323 // array as that's going to be the first value of the animation anyway
3324 if (Array.isArray(targetValue)) {
3325 value = targetValue[0];
3326 }
3327 // If it isn't a keyframes or the first keyframes value was set as `null`, read the
3328 // value from the DOM. It might be worth investigating whether to check props (for SVG)
3329 // or props.style (for HTML) if the value exists there before attempting to read.
3330 if (value === null) {
3331 value = this.readValueFromSource(key);
3332 invariant(value !== null, "No initial value for \"" + key + "\" can be inferred. Ensure an initial value for \"" + key + "\" is defined on the component.");
3333 }
3334 if (typeof value === "string" && isNumericalString(value)) {
3335 // If this is a number read as a string, ie "0" or "200", convert it to a number
3336 value = parseFloat(value);
3337 }
3338 else if (!getValueType$1(value) && complex.test(targetValue)) {
3339 // If value is not recognised as animatable, ie "none", create an animatable version origin based on the target
3340 value = complex.getAnimatableNone(targetValue);
3341 }
3342 this.values.set(key, motionValue(value));
3343 this.baseTarget[key] = value;
3344 }
3345 };
3346 /**
3347 * Resolve a variant from its label or resolver into an actual `Target` we can animate to.
3348 * @param variant -
3349 */
3350 ValueAnimationControls.prototype.resolveVariant = function (variant) {
3351 if (!variant) {
3352 return {
3353 target: undefined,
3354 transition: undefined,
3355 transitionEnd: undefined,
3356 };
3357 }
3358 if (isTargetResolver(variant)) {
3359 // resolve current and velocity
3360 variant = variant(this.props.custom, getCurrent(this.values), getVelocity(this.values));
3361 }
3362 var _a = variant.transition, transition = _a === void 0 ? this.defaultTransition : _a, transitionEnd = variant.transitionEnd, target = __rest(variant, ["transition", "transitionEnd"]);
3363 return { transition: transition, transitionEnd: transitionEnd, target: target };
3364 };
3365 /**
3366 * Get the highest active override priority index
3367 */
3368 ValueAnimationControls.prototype.getHighestPriority = function () {
3369 if (!this.activeOverrides.size)
3370 return 0;
3371 return Math.max.apply(Math, Array.from(this.activeOverrides));
3372 };
3373 /**
3374 * Set an override. We add this layer of indirection so if, for instance, a tap gesture
3375 * starts and overrides a hover gesture, when we clear the tap gesture and fallback to the
3376 * hover gesture, if that hover gesture has changed in the meantime we can go to that rather
3377 * than the one that was resolved when the hover gesture animation started.
3378 *
3379 * @param definition -
3380 * @param overrideIndex -
3381 */
3382 ValueAnimationControls.prototype.setOverride = function (definition, overrideIndex) {
3383 this.overrides[overrideIndex] = definition;
3384 if (this.children) {
3385 this.children.forEach(function (child) {
3386 return child.setOverride(definition, overrideIndex);
3387 });
3388 }
3389 };
3390 /**
3391 * Start an override animation.
3392 * @param overrideIndex -
3393 */
3394 ValueAnimationControls.prototype.startOverride = function (overrideIndex) {
3395 var override = this.overrides[overrideIndex];
3396 if (override) {
3397 return this.start(override, { priority: overrideIndex });
3398 }
3399 };
3400 /**
3401 * Clear an override. We check every value we animated to in this override to see if
3402 * its present on any lower-priority overrides. If not, we animate it back to its base target.
3403 * @param overrideIndex -
3404 */
3405 ValueAnimationControls.prototype.clearOverride = function (overrideIndex) {
3406 var _this = this;
3407 if (this.children) {
3408 this.children.forEach(function (child) { return child.clearOverride(overrideIndex); });
3409 }
3410 var override = this.overrides[overrideIndex];
3411 if (!override)
3412 return;
3413 this.activeOverrides.delete(overrideIndex);
3414 var highest = this.getHighestPriority();
3415 this.resetIsAnimating();
3416 if (highest) {
3417 var highestOverride = this.overrides[highest];
3418 highestOverride && this.startOverride(highest);
3419 }
3420 // Figure out which remaining values were affected by the override and animate those
3421 var overrideTarget = this.resolvedOverrides[overrideIndex];
3422 if (!overrideTarget)
3423 return;
3424 var remainingValues = {};
3425 for (var key in this.baseTarget) {
3426 if (overrideTarget[key] !== undefined) {
3427 remainingValues[key] = this.baseTarget[key];
3428 }
3429 }
3430 this.onStart();
3431 this.animate(remainingValues).then(function () { return _this.onComplete(); });
3432 };
3433 /**
3434 * Apply a target/variant without any animation
3435 */
3436 ValueAnimationControls.prototype.apply = function (definition) {
3437 if (Array.isArray(definition)) {
3438 return this.applyVariantLabels(definition);
3439 }
3440 else if (typeof definition === "string") {
3441 return this.applyVariantLabels([definition]);
3442 }
3443 else {
3444 this.setValues(definition);
3445 }
3446 };
3447 /**
3448 * Apply variant labels without animation
3449 */
3450 ValueAnimationControls.prototype.applyVariantLabels = function (variantLabelList) {
3451 var _this = this;
3452 var isActive = new Set();
3453 var reversedList = __spreadArrays(variantLabelList).reverse();
3454 reversedList.forEach(function (key) {
3455 var _a = _this.resolveVariant(_this.variants[key]), target = _a.target, transitionEnd = _a.transitionEnd;
3456 if (transitionEnd) {
3457 _this.setValues(transitionEnd, { isActive: isActive });
3458 }
3459 if (target) {
3460 _this.setValues(target, { isActive: isActive });
3461 }
3462 if (_this.children && _this.children.size) {
3463 _this.children.forEach(function (child) {
3464 return child.applyVariantLabels(variantLabelList);
3465 });
3466 }
3467 });
3468 };
3469 ValueAnimationControls.prototype.start = function (definition, opts) {
3470 var _this = this;
3471 if (opts === void 0) { opts = {}; }
3472 if (opts.priority) {
3473 this.activeOverrides.add(opts.priority);
3474 }
3475 this.resetIsAnimating(opts.priority);
3476 var animation;
3477 if (isVariantLabels(definition)) {
3478 animation = this.animateVariantLabels(definition, opts);
3479 }
3480 else if (typeof definition === "string") {
3481 animation = this.animateVariant(definition, opts);
3482 }
3483 else {
3484 animation = this.animate(definition, opts);
3485 }
3486 this.onStart();
3487 return animation.then(function () { return _this.onComplete(); });
3488 };
3489 ValueAnimationControls.prototype.animate = function (animationDefinition, _a) {
3490 var _this = this;
3491 var _b = _a === void 0 ? {} : _a, _c = _b.delay, delay = _c === void 0 ? 0 : _c, _d = _b.priority, priority = _d === void 0 ? 0 : _d, transitionOverride = _b.transitionOverride;
3492 var _e = this.resolveVariant(animationDefinition), target = _e.target, transition = _e.transition, transitionEnd = _e.transitionEnd;
3493 if (transitionOverride) {
3494 transition = transitionOverride;
3495 }
3496 if (!target)
3497 return Promise.resolve();
3498 target = this.transformValues(target);
3499 if (transitionEnd) {
3500 transitionEnd = this.transformValues(transitionEnd);
3501 }
3502 this.checkForNewValues(target);
3503 if (this.makeTargetAnimatable) {
3504 var animatable = this.makeTargetAnimatable(target, transitionEnd);
3505 target = animatable.target;
3506 transitionEnd = animatable.transitionEnd;
3507 }
3508 if (priority) {
3509 this.resolvedOverrides[priority] = target;
3510 }
3511 this.checkForNewValues(target);
3512 var animations = [];
3513 for (var key in target) {
3514 var value = this.values.get(key);
3515 if (!value || !target || target[key] === undefined)
3516 continue;
3517 var valueTarget = target[key];
3518 if (!priority) {
3519 this.baseTarget[key] = resolveFinalValueInKeyframes(valueTarget);
3520 }
3521 if (this.isAnimating.has(key))
3522 continue;
3523 this.isAnimating.add(key);
3524 animations.push(startAnimation(key, value, valueTarget, __assign({ delay: delay }, transition)));
3525 }
3526 var allAnimations = Promise.all(animations);
3527 return transitionEnd
3528 ? allAnimations.then(function () {
3529 _this.setValues(transitionEnd, { priority: priority });
3530 })
3531 : allAnimations;
3532 };
3533 ValueAnimationControls.prototype.animateVariantLabels = function (variantLabels, opts) {
3534 var _this = this;
3535 var animations = __spreadArrays(variantLabels).reverse()
3536 .map(function (label) { return _this.animateVariant(label, opts); });
3537 return Promise.all(animations);
3538 };
3539 ValueAnimationControls.prototype.animateVariant = function (variantLabel, opts) {
3540 var _this = this;
3541 var when = false;
3542 var delayChildren = 0;
3543 var staggerChildren = 0;
3544 var staggerDirection = 1;
3545 var priority = (opts && opts.priority) || 0;
3546 var variant = this.variants[variantLabel];
3547 var getAnimations = variant
3548 ? function () { return _this.animate(variant, opts); }
3549 : function () { return Promise.resolve(); };
3550 var getChildrenAnimations = this.children
3551 ? function () {
3552 return _this.animateChildren(variantLabel, delayChildren, staggerChildren, staggerDirection, priority);
3553 }
3554 : function () { return Promise.resolve(); };
3555 if (variant && this.children) {
3556 var transition = this.resolveVariant(variant).transition;
3557 if (transition) {
3558 when = transition.when || when;
3559 delayChildren = transition.delayChildren || delayChildren;
3560 staggerChildren = transition.staggerChildren || staggerChildren;
3561 staggerDirection =
3562 transition.staggerDirection || staggerDirection;
3563 }
3564 }
3565 if (when) {
3566 var _a = when === "beforeChildren"
3567 ? [getAnimations, getChildrenAnimations]
3568 : [getChildrenAnimations, getAnimations], first = _a[0], last = _a[1];
3569 return first().then(last);
3570 }
3571 else {
3572 return Promise.all([getAnimations(), getChildrenAnimations()]);
3573 }
3574 };
3575 ValueAnimationControls.prototype.animateChildren = function (variantLabel, delayChildren, staggerChildren, staggerDirection, priority) {
3576 if (delayChildren === void 0) { delayChildren = 0; }
3577 if (staggerChildren === void 0) { staggerChildren = 0; }
3578 if (staggerDirection === void 0) { staggerDirection = 1; }
3579 if (priority === void 0) { priority = 0; }
3580 if (!this.children) {
3581 return Promise.resolve();
3582 }
3583 var animations = [];
3584 var maxStaggerDuration = (this.children.size - 1) * staggerChildren;
3585 var generateStaggerDuration = staggerDirection === 1
3586 ? function (i) { return i * staggerChildren; }
3587 : function (i) { return maxStaggerDuration - i * staggerChildren; };
3588 Array.from(this.children).forEach(function (childControls, i) {
3589 var animation = childControls.animateVariant(variantLabel, {
3590 priority: priority,
3591 delay: delayChildren + generateStaggerDuration(i),
3592 });
3593 animations.push(animation);
3594 });
3595 return Promise.all(animations);
3596 };
3597 ValueAnimationControls.prototype.onStart = function () {
3598 var onAnimationStart = this.props.onAnimationStart;
3599 onAnimationStart && onAnimationStart();
3600 };
3601 ValueAnimationControls.prototype.onComplete = function () {
3602 var onAnimationComplete = this.props.onAnimationComplete;
3603 onAnimationComplete && onAnimationComplete();
3604 };
3605 ValueAnimationControls.prototype.checkOverrideIsAnimating = function (priority) {
3606 var numOverrides = this.overrides.length;
3607 for (var i = priority + 1; i < numOverrides; i++) {
3608 var resolvedOverride = this.resolvedOverrides[i];
3609 if (resolvedOverride) {
3610 for (var key in resolvedOverride) {
3611 this.isAnimating.add(key);
3612 }
3613 }
3614 }
3615 };
3616 ValueAnimationControls.prototype.resetIsAnimating = function (priority) {
3617 if (priority === void 0) { priority = 0; }
3618 this.isAnimating.clear();
3619 // If this isn't the highest priority gesture, block the animation
3620 // of anything that's currently being animated
3621 if (priority < this.getHighestPriority()) {
3622 this.checkOverrideIsAnimating(priority);
3623 }
3624 if (this.children) {
3625 this.children.forEach(function (child) { return child.resetIsAnimating(priority); });
3626 }
3627 };
3628 ValueAnimationControls.prototype.stop = function () {
3629 this.values.forEach(function (value) { return value.stop(); });
3630 };
3631 /**
3632 * Add the controls of a child component.
3633 * @param controls -
3634 */
3635 ValueAnimationControls.prototype.addChild = function (controls) {
3636 if (!this.children) {
3637 this.children = new Set();
3638 }
3639 this.children.add(controls);
3640 // We set child overrides when `setOverride` is called, but also have to do it here
3641 // as the first time `setOverride` is called all the children might not have been added yet.
3642 this.overrides.forEach(function (override, i) {
3643 override && controls.setOverride(override, i);
3644 });
3645 };
3646 ValueAnimationControls.prototype.removeChild = function (controls) {
3647 if (!this.children) {
3648 return;
3649 }
3650 this.children.delete(controls);
3651 };
3652 ValueAnimationControls.prototype.resetChildren = function () {
3653 if (this.children)
3654 this.children.clear();
3655 };
3656 return ValueAnimationControls;
3657 }());
3658
3659 /**
3660 * Use callback either only on the initial render or on all renders. In concurrent mode
3661 * the "initial" render might run multiple times
3662 *
3663 * @param callback - Callback to run
3664 * @param isInitialOnly - Set to `true` to only run on initial render, or `false` for all renders. Defaults to `false`.
3665 *
3666 * @public
3667 */
3668 function useInitialOrEveryRender(callback, isInitialOnly) {
3669 if (isInitialOnly === void 0) { isInitialOnly = false; }
3670 var isInitialRender = React.useRef(true);
3671 if (!isInitialOnly || (isInitialOnly && isInitialRender.current)) {
3672 callback();
3673 }
3674 isInitialRender.current = false;
3675 }
3676
3677 /**
3678 * Control animations on one or more components.
3679 *
3680 * @public
3681 */
3682 var AnimationControls = /** @class */ (function () {
3683 function AnimationControls() {
3684 /**
3685 * Track whether the host component has mounted.
3686 *
3687 * @internal
3688 */
3689 this.hasMounted = false;
3690 /**
3691 * Pending animations that are started before a component is mounted.
3692 *
3693 * @internal
3694 */
3695 this.pendingAnimations = [];
3696 /**
3697 * A collection of linked component animation controls.
3698 *
3699 * @internal
3700 */
3701 this.componentControls = new Set();
3702 }
3703 /**
3704 * Set variants on this and all child components.
3705 *
3706 * @param variants - The variants to set
3707 *
3708 * @internal
3709 */
3710 AnimationControls.prototype.setVariants = function (variants) {
3711 this.variants = variants;
3712 this.componentControls.forEach(function (controls) {
3713 return controls.setVariants(variants);
3714 });
3715 };
3716 /**
3717 * Set a default transition on this and all child components
3718 *
3719 * @param transition - The default transition to set
3720 *
3721 * @internal
3722 */
3723 AnimationControls.prototype.setDefaultTransition = function (transition) {
3724 this.defaultTransition = transition;
3725 this.componentControls.forEach(function (controls) {
3726 return controls.setDefaultTransition(transition);
3727 });
3728 };
3729 /**
3730 * Subscribes a component's animation controls to this.
3731 *
3732 * @param controls - The controls to subscribe
3733 * @returns An unsubscribe function.
3734 *
3735 * @internal
3736 */
3737 AnimationControls.prototype.subscribe = function (controls) {
3738 var _this = this;
3739 this.componentControls.add(controls);
3740 if (this.variants)
3741 controls.setVariants(this.variants);
3742 if (this.defaultTransition)
3743 controls.setDefaultTransition(this.defaultTransition);
3744 return function () { return _this.componentControls.delete(controls); };
3745 };
3746 /**
3747 * Starts an animation on all linked components.
3748 *
3749 * @remarks
3750 *
3751 * ```jsx
3752 * controls.start("variantLabel")
3753 * controls.start({
3754 * x: 0,
3755 * transition: { duration: 1 }
3756 * })
3757 * ```
3758 *
3759 * @param definition - Properties or variant label to animate to
3760 * @param transition - Optional `transtion` to apply to a variant
3761 * @returns - A `Promise` that resolves when all animations have completed.
3762 *
3763 * @public
3764 */
3765 AnimationControls.prototype.start = function (definition, transitionOverride) {
3766 var _this = this;
3767 if (this.hasMounted) {
3768 var animations_1 = [];
3769 this.componentControls.forEach(function (controls) {
3770 var animation = controls.start(definition, {
3771 transitionOverride: transitionOverride,
3772 });
3773 animations_1.push(animation);
3774 });
3775 return Promise.all(animations_1);
3776 }
3777 else {
3778 return new Promise(function (resolve) {
3779 _this.pendingAnimations.push({
3780 animation: [definition, transitionOverride],
3781 resolve: resolve,
3782 });
3783 });
3784 }
3785 };
3786 /**
3787 * Instantly set to a set of properties or a variant.
3788 *
3789 * ```jsx
3790 * // With properties
3791 * controls.set({ opacity: 0 })
3792 *
3793 * // With variants
3794 * controls.set("hidden")
3795 * ```
3796 *
3797 * @internalremarks
3798 * We could perform a similar trick to `.start` where this can be called before mount
3799 * and we maintain a list of of pending actions that get applied on mount. But the
3800 * expectation of `set` is that it happens synchronously and this would be difficult
3801 * to do before any children have even attached themselves. It's also poor practise
3802 * and we should discourage render-synchronous `.start` calls rather than lean into this.
3803 *
3804 * @public
3805 */
3806 AnimationControls.prototype.set = function (definition) {
3807 invariant(this.hasMounted, "controls.set() should only be called after a component has mounted. Consider calling within a useEffect hook.");
3808 return this.componentControls.forEach(function (controls) {
3809 return controls.apply(definition);
3810 });
3811 };
3812 /**
3813 * Stops animations on all linked components.
3814 *
3815 * ```jsx
3816 * controls.stop()
3817 * ```
3818 *
3819 * @public
3820 */
3821 AnimationControls.prototype.stop = function () {
3822 this.componentControls.forEach(function (controls) { return controls.stop(); });
3823 };
3824 /**
3825 * Initialises the animation controls.
3826 *
3827 * @internal
3828 */
3829 AnimationControls.prototype.mount = function () {
3830 var _this = this;
3831 this.hasMounted = true;
3832 this.pendingAnimations.forEach(function (_a) {
3833 var animation = _a.animation, resolve = _a.resolve;
3834 return _this.start.apply(_this, animation).then(resolve);
3835 });
3836 };
3837 /**
3838 * Stops all child animations when the host component unmounts.
3839 *
3840 * @internal
3841 */
3842 AnimationControls.prototype.unmount = function () {
3843 this.hasMounted = false;
3844 this.stop();
3845 };
3846 return AnimationControls;
3847 }());
3848 /**
3849 * @internal
3850 */
3851 var animationControls = function () { return new AnimationControls(); };
3852
3853 /**
3854 * @internal
3855 */
3856 var MotionContext = React.createContext({
3857 static: false,
3858 });
3859 var isVariantLabel = function (v) {
3860 return typeof v === "string" || Array.isArray(v);
3861 };
3862 var isAnimationControls = function (v) {
3863 return v instanceof AnimationControls;
3864 };
3865 /**
3866 * Set up the context for children motion components.
3867 *
3868 * We also use this opportunity to apply `initial` values
3869 */
3870 var useMotionContext = function (parentContext, controls, values, isStatic, _a) {
3871 if (isStatic === void 0) { isStatic = false; }
3872 var initial = _a.initial, animate = _a.animate, variants = _a.variants, whileTap = _a.whileTap, whileHover = _a.whileHover;
3873 // Override initial with that from a parent context, if defined
3874 if (parentContext.exitProps &&
3875 parentContext.exitProps.initial !== undefined) {
3876 initial = parentContext.exitProps.initial;
3877 }
3878 var initialState;
3879 if (initial === false && !isAnimationControls(animate)) {
3880 initialState = animate;
3881 }
3882 else if (typeof initial !== "boolean") {
3883 initialState = initial;
3884 }
3885 // Track mounted status so children can detect whether they were present during their
3886 // parent's first render
3887 var hasMounted = React.useRef(false);
3888 // We propagate this component's ValueAnimationControls *if* we're being provided variants,
3889 // if we're being used to control variants, or if we're being passed animation controls.
3890 // Otherwise this component should be "invisible" to variant propagation. This is a slight concession
3891 // to Framer X where every `Frame` is a `motion` component and it might be if we change that in the future
3892 // that this restriction is removed.
3893 var shouldPropagateControls = variants ||
3894 isVariantLabel(animate) ||
3895 isVariantLabel(whileTap) ||
3896 isVariantLabel(whileHover) ||
3897 isAnimationControls(animate);
3898 // If this component's `initial` prop is a variant label, propagate it. Otherwise pass the parent's.
3899 var targetInitial = isVariantLabel(initialState)
3900 ? initialState
3901 : parentContext.initial;
3902 // If this is a variant tree we need to propagate the `animate` prop in case new children are added after
3903 // the tree initially animates.
3904 var targetAnimate = isVariantLabel(animate)
3905 ? animate
3906 : parentContext.animate;
3907 // Only allow `initial` to trigger context re-renders if this is a `static` component (ie we're on the Framer canvas)
3908 // or in another non-animation/interaction environment.
3909 var initialDependency = isStatic ? targetInitial : null;
3910 // Only allow `animate` to trigger context re-renders if it's a variant label. If this is an array of
3911 // variant labels there's probably an optimisation to deep-compare but it might be an over-optimisation.
3912 // We want to do this as we rely on React's component rendering order each render cycle to determine
3913 // the new order of any child components for the `staggerChildren` functionality.
3914 var animateDependency = shouldPropagateControls && isVariantLabel(targetAnimate)
3915 ? targetAnimate
3916 : null;
3917 // The context to provide to the child. We `useMemo` because although `controls` and `initial` are
3918 // unlikely to change, by making the context an object it'll be considered a new value every render.
3919 // So all child motion components will re-render as a result.
3920 var context = React.useMemo(function () { return ({
3921 controls: shouldPropagateControls
3922 ? controls
3923 : parentContext.controls,
3924 initial: targetInitial,
3925 animate: targetAnimate,
3926 values: values,
3927 hasMounted: hasMounted,
3928 isReducedMotion: parentContext.isReducedMotion,
3929 }); }, [initialDependency, animateDependency, parentContext.isReducedMotion]);
3930 // Update the `static` property every render. This is unlikely to change but also essentially free.
3931 context.static = isStatic;
3932 // Set initial state. If this is a static component (ie in Framer canvas), respond to updates
3933 // in `initial`.
3934 useInitialOrEveryRender(function () {
3935 var initialToApply = initialState || parentContext.initial;
3936 initialToApply && controls.apply(initialToApply);
3937 }, !isStatic);
3938 React.useEffect(function () {
3939 hasMounted.current = true;
3940 }, []);
3941 return context;
3942 };
3943
3944 /**
3945 * Creates an imperative set of controls to trigger animations.
3946 *
3947 * This allows a consolidated, uniform API for animations, to be triggered by other APIs like the `animate` prop, or the gesture handlers.
3948 *
3949 * @param values
3950 * @param props
3951 * @param ref
3952 * @param subscribeToParentControls
3953 *
3954 * @internal
3955 */
3956 function useValueAnimationControls(config, props, subscribeToParentControls, parentContext) {
3957 var variants = props.variants, transition = props.transition;
3958 var parentControls = React.useContext(MotionContext).controls;
3959 var controls = useConstant(function () { return new ValueAnimationControls(config); });
3960 // Reset and resubscribe children every render to ensure stagger order is correct
3961 if (!parentContext ||
3962 !parentContext.exitProps ||
3963 !parentContext.exitProps.isExiting) {
3964 controls.resetChildren();
3965 controls.setProps(props);
3966 controls.setVariants(variants);
3967 controls.setDefaultTransition(transition);
3968 }
3969 // We have to subscribe to the parent controls within a useEffect rather than during render,
3970 // as
3971 React.useEffect(function () {
3972 if (subscribeToParentControls && parentControls) {
3973 parentControls.addChild(controls);
3974 }
3975 });
3976 React.useEffect(function () {
3977 return function () {
3978 // Remove reference to onAnimationComplete from controls. All the MotionValues
3979 // are unsubscribed from this component separately. We let animations run out
3980 // as they might be animating other components.
3981 var onAnimationComplete = props.onAnimationComplete, unmountProps = __rest(props, ["onAnimationComplete"]);
3982 controls.setProps(unmountProps);
3983 parentControls && parentControls.removeChild(controls);
3984 };
3985 }, []);
3986 return controls;
3987 }
3988
3989 var checkShouldInheritVariant = function (_a) {
3990 var animate = _a.animate, variants = _a.variants, _b = _a.inherit, inherit = _b === void 0 ? true : _b;
3991 return (inherit &&
3992 !!variants &&
3993 (!animate || animate instanceof AnimationControls));
3994 };
3995
3996 /**
3997 * Uses the ref that is passed in, or creates a new one
3998 * @param external - External ref
3999 * @internal
4000 */
4001 function useExternalRef(externalRef) {
4002 // We're conditionally calling `useRef` here which is sort of naughty as hooks
4003 // shouldn't be called conditionally. However, Framer Motion will break if this
4004 // condition changes anyway. It might be possible to use an invariant here to
4005 // make it explicit, but I expect changing `ref` is not normal behaviour.
4006 var ref = !externalRef || typeof externalRef === "function"
4007 ? React.useRef(null)
4008 : externalRef;
4009 // Handle `ref` functions. Again, calling the hook conditionally is kind of naughty
4010 // but `ref` types changing between renders would break Motion anyway. If we receive
4011 // bug reports about this, we should track the provided ref and throw an invariant
4012 // rather than move the conditional to inside the useEffect as this will be fired
4013 // for every Frame component within Framer.
4014 if (externalRef && typeof externalRef === "function") {
4015 React.useEffect(function () {
4016 externalRef(ref.current);
4017 return function () { return externalRef(null); };
4018 }, []);
4019 }
4020 return ref;
4021 }
4022
4023 /**
4024 * @internal
4025 */
4026 var createMotionComponent = function (_a) {
4027 var getValueControlsConfig = _a.getValueControlsConfig, loadFunctionalityComponents = _a.loadFunctionalityComponents, renderComponent = _a.renderComponent;
4028 function MotionComponent(props, externalRef) {
4029 var ref = useExternalRef(externalRef);
4030 var parentContext = React.useContext(MotionContext);
4031 var isStatic = parentContext.static || props.static || false;
4032 var values = useMotionValues(props);
4033 var style = useMotionStyles(values, props.style, isStatic, props.transformValues);
4034 var shouldInheritVariant = checkShouldInheritVariant(props);
4035 var controlsConfig = useConstant(function () {
4036 return getValueControlsConfig(ref, values);
4037 });
4038 var controls = useValueAnimationControls(controlsConfig, props, shouldInheritVariant, parentContext);
4039 var context = useMotionContext(parentContext, controls, values, isStatic, props);
4040 var functionality = isStatic
4041 ? null
4042 : loadFunctionalityComponents(ref, values, props, parentContext, controls, shouldInheritVariant);
4043 var renderedComponent = renderComponent(ref, style, values, props, isStatic);
4044 return (React.createElement(React.Fragment, null,
4045 React.createElement(MotionContext.Provider, { value: context }, renderedComponent),
4046 React.createElement(React.Fragment, null,
4047 React.createElement(Mount, { innerRef: ref, values: values, isStatic: isStatic }),
4048 functionality)));
4049 }
4050 return React.forwardRef(MotionComponent);
4051 };
4052
4053 /**
4054 * @internal
4055 */
4056 var htmlElements = [
4057 "a",
4058 "abbr",
4059 "address",
4060 "area",
4061 "article",
4062 "aside",
4063 "audio",
4064 "b",
4065 "base",
4066 "bdi",
4067 "bdo",
4068 "big",
4069 "blockquote",
4070 "body",
4071 "br",
4072 "button",
4073 "canvas",
4074 "caption",
4075 "cite",
4076 "code",
4077 "col",
4078 "colgroup",
4079 "data",
4080 "datalist",
4081 "dd",
4082 "del",
4083 "details",
4084 "dfn",
4085 "dialog",
4086 "div",
4087 "dl",
4088 "dt",
4089 "em",
4090 "embed",
4091 "fieldset",
4092 "figcaption",
4093 "figure",
4094 "footer",
4095 "form",
4096 "h1",
4097 "h2",
4098 "h3",
4099 "h4",
4100 "h5",
4101 "h6",
4102 "head",
4103 "header",
4104 "hgroup",
4105 "hr",
4106 "html",
4107 "i",
4108 "iframe",
4109 "img",
4110 "input",
4111 "ins",
4112 "kbd",
4113 "keygen",
4114 "label",
4115 "legend",
4116 "li",
4117 "link",
4118 "main",
4119 "map",
4120 "mark",
4121 "menu",
4122 "menuitem",
4123 "meta",
4124 "meter",
4125 "nav",
4126 "noscript",
4127 "object",
4128 "ol",
4129 "optgroup",
4130 "option",
4131 "output",
4132 "p",
4133 "param",
4134 "picture",
4135 "pre",
4136 "progress",
4137 "q",
4138 "rp",
4139 "rt",
4140 "ruby",
4141 "s",
4142 "samp",
4143 "script",
4144 "section",
4145 "select",
4146 "small",
4147 "source",
4148 "span",
4149 "strong",
4150 "style",
4151 "sub",
4152 "summary",
4153 "sup",
4154 "table",
4155 "tbody",
4156 "td",
4157 "textarea",
4158 "tfoot",
4159 "th",
4160 "thead",
4161 "time",
4162 "title",
4163 "tr",
4164 "track",
4165 "u",
4166 "ul",
4167 "var",
4168 "video",
4169 "wbr",
4170 "webview",
4171 ];
4172 /**
4173 * @internal
4174 */
4175 var svgElements = [
4176 "animate",
4177 "circle",
4178 "clipPath",
4179 "defs",
4180 "desc",
4181 "ellipse",
4182 "feBlend",
4183 "feColorMatrix",
4184 "feComponentTransfer",
4185 "feComposite",
4186 "feConvolveMatrix",
4187 "feDiffuseLighting",
4188 "feDisplacementMap",
4189 "feDistantLight",
4190 "feDropShadow",
4191 "feFlood",
4192 "feFuncA",
4193 "feFuncB",
4194 "feFuncG",
4195 "feFuncR",
4196 "feGaussianBlur",
4197 "feImage",
4198 "feMerge",
4199 "feMergeNode",
4200 "feMorphology",
4201 "feOffset",
4202 "fePointLight",
4203 "feSpecularLighting",
4204 "feSpotLight",
4205 "feTile",
4206 "feTurbulence",
4207 "filter",
4208 "foreignObject",
4209 "g",
4210 "image",
4211 "line",
4212 "linearGradient",
4213 "marker",
4214 "mask",
4215 "metadata",
4216 "path",
4217 "pattern",
4218 "polygon",
4219 "polyline",
4220 "radialGradient",
4221 "rect",
4222 "stop",
4223 "svg",
4224 "switch",
4225 "symbol",
4226 "text",
4227 "textPath",
4228 "tspan",
4229 "use",
4230 "view",
4231 ];
4232
4233 /**
4234 * @internal
4235 */
4236 var MotionPluginContext = React.createContext({
4237 transformPagePoint: function (p) { return p; },
4238 });
4239 /**
4240 * @remarks For now I think this should remain a private API for our own use
4241 * until we can figure out a nicer way of allowing people to add these
4242 *
4243 * @internal
4244 */
4245 function MotionPlugins(_a) {
4246 var children = _a.children, props = __rest(_a, ["children"]);
4247 var pluginContext = React.useContext(MotionPluginContext);
4248 var value = React.useRef(__assign({}, pluginContext)).current;
4249 // Mutative to prevent triggering rerenders in all listening
4250 // components every time this component renders
4251 for (var key in props) {
4252 value[key] = props[key];
4253 }
4254 return (React.createElement(MotionPluginContext.Provider, { value: value }, children));
4255 }
4256
4257 function useUnmountEffect(callback) {
4258 return React.useEffect(function () { return function () { return callback(); }; }, []);
4259 }
4260
4261 function addDomEvent(target, eventName, handler, options) {
4262 if (!handler)
4263 return;
4264 target.addEventListener(eventName, handler, options);
4265 return function () { return target.removeEventListener(eventName, handler, options); };
4266 }
4267 /**
4268 * Attaches an event listener directly to the provided DOM element.
4269 *
4270 * Bypassing React's event system can be desirable, for instance when attaching non-passive
4271 * event handlers.
4272 *
4273 * ```jsx
4274 * const ref = useRef(null)
4275 *
4276 * useDomEvent(ref, 'wheel', onWheel, { passive: false })
4277 *
4278 * return <div ref={ref} />
4279 * ```
4280 *
4281 * @param ref - React.RefObject that's been provided to the element you want to bind the listener to.
4282 * @param eventName - Name of the event you want listen for.
4283 * @param handler - Function to fire when receiving the event.
4284 * @param options - Options to pass to `Event.addEventListener`.
4285 *
4286 * @public
4287 */
4288 function useDomEvent(ref, eventName, handler, options) {
4289 React.useEffect(function () {
4290 var element = ref.current;
4291 if (handler && element) {
4292 return addDomEvent(element, eventName, handler, options);
4293 }
4294 }, [ref, eventName, handler, options]);
4295 }
4296
4297 function isMouseEvent(event) {
4298 // PointerEvent inherits from MouseEvent so we can't use a straight instanceof check.
4299 if (typeof PointerEvent !== "undefined" && event instanceof PointerEvent) {
4300 return !!(event.pointerType === "mouse");
4301 }
4302 return event instanceof MouseEvent;
4303 }
4304 function isTouchEvent(event) {
4305 var hasTouches = !!event.touches;
4306 return hasTouches;
4307 }
4308
4309 /**
4310 * Filters out events not attached to the primary pointer (currently left mouse button)
4311 * @param eventHandler
4312 */
4313 function filterPrimaryPointer(eventHandler) {
4314 if (!eventHandler)
4315 return undefined;
4316 return function (event) {
4317 var isMouseEvent = event instanceof MouseEvent;
4318 var isPrimaryPointer = !isMouseEvent ||
4319 (isMouseEvent && event.button === 0);
4320 if (isPrimaryPointer) {
4321 eventHandler(event);
4322 }
4323 };
4324 }
4325 var defaultPagePoint = { pageX: 0, pageY: 0 };
4326 function pointFromTouch(e) {
4327 var primaryTouch = e.touches[0] || e.changedTouches[0];
4328 var _a = primaryTouch || defaultPagePoint, pageX = _a.pageX, pageY = _a.pageY;
4329 return { x: pageX, y: pageY };
4330 }
4331 function pointFromMouse(_a) {
4332 var _b = _a.pageX, pageX = _b === void 0 ? 0 : _b, _c = _a.pageY, pageY = _c === void 0 ? 0 : _c;
4333 return { x: pageX, y: pageY };
4334 }
4335 function extractEventInfo(event) {
4336 return {
4337 point: isTouchEvent(event)
4338 ? pointFromTouch(event)
4339 : pointFromMouse(event),
4340 };
4341 }
4342 var wrapHandler = function (handler, shouldFilterPrimaryPointer) {
4343 if (shouldFilterPrimaryPointer === void 0) { shouldFilterPrimaryPointer = false; }
4344 if (!handler)
4345 return;
4346 var listener = function (event) { return handler(event, extractEventInfo(event)); };
4347 return shouldFilterPrimaryPointer
4348 ? filterPrimaryPointer(listener)
4349 : listener;
4350 };
4351
4352 var isBrowser$1 = typeof window !== "undefined";
4353 // We check for event support via functions in case they've been mocked by a testing suite.
4354 var supportsPointerEvents = function () {
4355 return isBrowser$1 && window.onpointerdown === null;
4356 };
4357 var supportsTouchEvents = function () {
4358 return isBrowser$1 && window.ontouchstart === null;
4359 };
4360 var supportsMouseEvents = function () {
4361 return isBrowser$1 && window.onmousedown === null;
4362 };
4363
4364 var mouseEventNames = {
4365 pointerdown: "mousedown",
4366 pointermove: "mousemove",
4367 pointerup: "mouseup",
4368 pointercancel: "mousecancel",
4369 pointerover: "mouseover",
4370 pointerout: "mouseout",
4371 pointerenter: "mouseenter",
4372 pointerleave: "mouseleave",
4373 };
4374 var touchEventNames = {
4375 pointerdown: "touchstart",
4376 pointermove: "touchmove",
4377 pointerup: "touchend",
4378 pointercancel: "touchcancel",
4379 };
4380 function getPointerEventName(name) {
4381 if (supportsPointerEvents()) {
4382 return name;
4383 }
4384 else if (supportsTouchEvents()) {
4385 return touchEventNames[name];
4386 }
4387 else if (supportsMouseEvents()) {
4388 return mouseEventNames[name];
4389 }
4390 return name;
4391 }
4392 function addPointerEvent(target, eventName, handler, options) {
4393 return addDomEvent(target, getPointerEventName(eventName), wrapHandler(handler, eventName === "pointerdown"), options);
4394 }
4395 function usePointerEvent(ref, eventName, handler, options) {
4396 return useDomEvent(ref, getPointerEventName(eventName), wrapHandler(handler, eventName === "pointerdown"), options);
4397 }
4398
4399 /** @public */
4400 (function (Point) {
4401 /** @beta */
4402 Point.subtract = function (a, b) {
4403 return { x: a.x - b.x, y: a.y - b.y };
4404 };
4405 /** @beta */
4406 Point.relativeTo = function (idOrElem) {
4407 var elem;
4408 var getElem = function () {
4409 // Caching element here could be leaky because of React lifecycle
4410 if (elem !== undefined)
4411 return elem;
4412 if (typeof idOrElem === "string") {
4413 elem = document.getElementById(idOrElem);
4414 }
4415 else {
4416 elem = idOrElem;
4417 }
4418 return elem;
4419 };
4420 return function (_a) {
4421 var x = _a.x, y = _a.y;
4422 var localElem = getElem();
4423 if (!localElem)
4424 return undefined;
4425 var rect = localElem.getBoundingClientRect();
4426 return {
4427 x: x - rect.left - window.scrollX,
4428 y: y - rect.top - window.scrollY,
4429 };
4430 };
4431 };
4432 })(exports.Point || (exports.Point = {}));
4433
4434 var isViewportScrollBlocked = false;
4435 var isBrowser$2 = typeof window !== "undefined";
4436 if (isBrowser$2) {
4437 document.addEventListener("touchmove", function (event) {
4438 if (isViewportScrollBlocked) {
4439 event.preventDefault();
4440 }
4441 }, { passive: false });
4442 }
4443 var blockViewportScroll = function () { return (isViewportScrollBlocked = true); };
4444 var unblockViewportScroll = function () { return (isViewportScrollBlocked = false); };
4445
4446 /**
4447 * @internal
4448 */
4449 var PanSession = /** @class */ (function () {
4450 function PanSession(event, handlers, _a) {
4451 var _this = this;
4452 var transformPagePoint = (_a === void 0 ? {} : _a).transformPagePoint;
4453 /**
4454 * @internal
4455 */
4456 this.startEvent = null;
4457 /**
4458 * @internal
4459 */
4460 this.lastMoveEvent = null;
4461 /**
4462 * @internal
4463 */
4464 this.lastMoveEventInfo = null;
4465 /**
4466 * @internal
4467 */
4468 this.handlers = {};
4469 this.updatePoint = function () {
4470 if (!(_this.lastMoveEvent && _this.lastMoveEventInfo))
4471 return;
4472 var info = getPanInfo(_this.lastMoveEventInfo, _this.history);
4473 var isPanStarted = _this.startEvent !== null;
4474 // Only start panning if the offset is larger than 3 pixels. If we make it
4475 // any larger than this we'll want to reset the pointer history
4476 // on the first update to avoid visual snapping to the cursoe.
4477 var isDistancePastThreshold = distance(info.offset, { x: 0, y: 0 }) >= 3;
4478 if (!isPanStarted && !isDistancePastThreshold)
4479 return;
4480 var point = info.point;
4481 var timestamp = getFrameData().timestamp;
4482 _this.history.push(__assign(__assign({}, point), { timestamp: timestamp }));
4483 var _a = _this.handlers, onStart = _a.onStart, onMove = _a.onMove;
4484 if (!isPanStarted) {
4485 onStart && onStart(_this.lastMoveEvent, info);
4486 _this.startEvent = _this.lastMoveEvent;
4487 }
4488 onMove && onMove(_this.lastMoveEvent, info);
4489 };
4490 // If we have more than one touch, don't start detecting this gesture
4491 if (isTouchEvent(event) && event.touches.length > 1)
4492 return;
4493 this.handlers = handlers;
4494 this.transformPagePoint = transformPagePoint;
4495 var info = extractEventInfo(event);
4496 var initialInfo = transformPoint(info, this.transformPagePoint);
4497 var point = initialInfo.point;
4498 var timestamp = getFrameData().timestamp;
4499 this.history = [__assign(__assign({}, point), { timestamp: timestamp })];
4500 var onSessionStart = handlers.onSessionStart;
4501 onSessionStart &&
4502 onSessionStart(event, getPanInfo(initialInfo, this.history));
4503 var removeOnPointerMove = addPointerEvent(window, "pointermove", function (event, info) { return _this.handlePointerMove(event, info); });
4504 var removeOnPointerUp = addPointerEvent(window, "pointerup", function (event, info) { return _this.handlePointerUp(event, info); });
4505 this.removeListeners = function () {
4506 removeOnPointerMove && removeOnPointerMove();
4507 removeOnPointerUp && removeOnPointerUp();
4508 };
4509 }
4510 PanSession.prototype.handlePointerMove = function (event, info) {
4511 this.lastMoveEvent = event;
4512 this.lastMoveEventInfo = transformPoint(info, this.transformPagePoint);
4513 // Because Safari doesn't trigger mouseup events when it's above a `<select>`
4514 if (isMouseEvent(event) && event.buttons === 0) {
4515 this.handlePointerUp(event, info);
4516 return;
4517 }
4518 // Throttle mouse move event to once per frame
4519 sync.update(this.updatePoint, true);
4520 };
4521 PanSession.prototype.handlePointerUp = function (event, info) {
4522 this.end();
4523 var onEnd = this.handlers.onEnd;
4524 if (!onEnd)
4525 return;
4526 var panInfo = getPanInfo(transformPoint(info, this.transformPagePoint), this.history);
4527 onEnd && onEnd(event, panInfo);
4528 };
4529 PanSession.prototype.updateHandlers = function (handlers) {
4530 this.handlers = handlers;
4531 };
4532 PanSession.prototype.end = function () {
4533 this.removeListeners && this.removeListeners();
4534 cancelSync.update(this.updatePoint);
4535 unblockViewportScroll();
4536 };
4537 return PanSession;
4538 }());
4539 function transformPoint(info, transformPagePoint) {
4540 return transformPagePoint ? { point: transformPagePoint(info.point) } : info;
4541 }
4542 function getPanInfo(_a, history) {
4543 var point = _a.point;
4544 return {
4545 point: point,
4546 delta: exports.Point.subtract(point, lastDevicePoint(history)),
4547 offset: exports.Point.subtract(point, startDevicePoint(history)),
4548 velocity: getVelocity$1(history, 0.1),
4549 };
4550 }
4551 function startDevicePoint(history) {
4552 return history[0];
4553 }
4554 function lastDevicePoint(history) {
4555 return history[history.length - 1];
4556 }
4557 function getVelocity$1(history, timeDelta) {
4558 if (history.length < 2) {
4559 return { x: 0, y: 0 };
4560 }
4561 var i = history.length - 1;
4562 var timestampedPoint = null;
4563 var lastPoint = lastDevicePoint(history);
4564 while (i >= 0) {
4565 timestampedPoint = history[i];
4566 if (lastPoint.timestamp - timestampedPoint.timestamp >
4567 secondsToMilliseconds(timeDelta)) {
4568 break;
4569 }
4570 i--;
4571 }
4572 if (!timestampedPoint) {
4573 return { x: 0, y: 0 };
4574 }
4575 var time = (lastPoint.timestamp - timestampedPoint.timestamp) / 1000;
4576 if (time === 0) {
4577 return { x: 0, y: 0 };
4578 }
4579 var currentVelocity = {
4580 x: (lastPoint.x - timestampedPoint.x) / time,
4581 y: (lastPoint.y - timestampedPoint.y) / time,
4582 };
4583 if (currentVelocity.x === Infinity) {
4584 currentVelocity.x = 0;
4585 }
4586 if (currentVelocity.y === Infinity) {
4587 currentVelocity.y = 0;
4588 }
4589 return currentVelocity;
4590 }
4591
4592 /**
4593 *
4594 * @param handlers -
4595 * @param ref -
4596 *
4597 * @internalremarks
4598 * Currently this sets new pan gesture functions every render. The memo route has been explored
4599 * in the past but ultimately we're still creating new functions every render. An optimisation
4600 * to explore is creating the pan gestures and loading them into a `ref`.
4601 *
4602 * @internal
4603 */
4604 function usePanGesture(_a, ref) {
4605 var onPan = _a.onPan, onPanStart = _a.onPanStart, onPanEnd = _a.onPanEnd, onPanSessionStart = _a.onPanSessionStart;
4606 var hasPanEvents = onPan || onPanStart || onPanEnd || onPanSessionStart;
4607 var panSession = React.useRef(null);
4608 var transformPagePoint = React.useContext(MotionPluginContext).transformPagePoint;
4609 var handlers = {
4610 onSessionStart: onPanSessionStart,
4611 onStart: onPanStart,
4612 onMove: onPan,
4613 onEnd: function (event, info) {
4614 panSession.current = null;
4615 onPanEnd && onPanEnd(event, info);
4616 },
4617 };
4618 if (panSession.current !== null) {
4619 panSession.current.updateHandlers(handlers);
4620 }
4621 function onPointerDown(event) {
4622 panSession.current = new PanSession(event, handlers, {
4623 transformPagePoint: transformPagePoint,
4624 });
4625 }
4626 usePointerEvent(ref, "pointerdown", hasPanEvents && onPointerDown);
4627 useUnmountEffect(function () { return panSession.current && panSession.current.end(); });
4628 }
4629
4630 /**
4631 * Recursively traverse up the tree to check whether the provided child node
4632 * is the parent or a descendant of it.
4633 *
4634 * @param parent - Element to find
4635 * @param child - Element to test against parent
4636 */
4637 var isNodeOrChild = function (parent, child) {
4638 if (!child) {
4639 return false;
4640 }
4641 else if (parent === child) {
4642 return true;
4643 }
4644 else {
4645 return isNodeOrChild(parent, child.parentElement);
4646 }
4647 };
4648
4649 var order$1 = ["whileHover", "whileTap", "whileDrag"];
4650 var getGesturePriority = function (gesture) {
4651 return order$1.indexOf(gesture) + 1;
4652 };
4653
4654 function createLock(name) {
4655 var lock = null;
4656 return function () {
4657 var openLock = function () {
4658 lock = null;
4659 };
4660 if (lock === null) {
4661 lock = name;
4662 return openLock;
4663 }
4664 return false;
4665 };
4666 }
4667 var globalHorizontalLock = createLock("dragHorizontal");
4668 var globalVerticalLock = createLock("dragVertical");
4669 function getGlobalLock(drag) {
4670 var lock = false;
4671 if (drag === "y") {
4672 lock = globalVerticalLock();
4673 }
4674 else if (drag === "x") {
4675 lock = globalHorizontalLock();
4676 }
4677 else {
4678 var openHorizontal_1 = globalHorizontalLock();
4679 var openVertical_1 = globalVerticalLock();
4680 if (openHorizontal_1 && openVertical_1) {
4681 lock = function () {
4682 openHorizontal_1();
4683 openVertical_1();
4684 };
4685 }
4686 else {
4687 // Release the locks because we don't use them
4688 if (openHorizontal_1)
4689 openHorizontal_1();
4690 if (openVertical_1)
4691 openVertical_1();
4692 }
4693 }
4694 return lock;
4695 }
4696
4697 var tapGesturePriority = getGesturePriority("whileTap");
4698 /**
4699 * @param handlers -
4700 * @internal
4701 */
4702 function useTapGesture(_a, ref) {
4703 var onTap = _a.onTap, onTapStart = _a.onTapStart, onTapCancel = _a.onTapCancel, whileTap = _a.whileTap, controls = _a.controls;
4704 var hasTapListeners = onTap || onTapStart || onTapCancel || whileTap;
4705 var isTapping = React.useRef(false);
4706 var cancelPointerEventListener = React.useRef(null);
4707 function removePointerUp() {
4708 cancelPointerEventListener.current &&
4709 cancelPointerEventListener.current();
4710 cancelPointerEventListener.current = null;
4711 }
4712 if (whileTap && controls) {
4713 controls.setOverride(whileTap, tapGesturePriority);
4714 }
4715 // We load this event handler into a ref so we can later refer to
4716 // onPointerUp.current which will always have reference to the latest props
4717 var onPointerUp = React.useRef(null);
4718 onPointerUp.current = function (event, info) {
4719 var element = ref.current;
4720 removePointerUp();
4721 if (!isTapping.current || !element)
4722 return;
4723 isTapping.current = false;
4724 if (controls && whileTap) {
4725 controls.clearOverride(tapGesturePriority);
4726 }
4727 // Check the gesture lock - if we get it, it means no drag gesture is active
4728 // and we can safely fire the tap gesture.
4729 var openGestureLock = getGlobalLock(true);
4730 if (!openGestureLock)
4731 return;
4732 openGestureLock();
4733 if (!isNodeOrChild(element, event.target)) {
4734 onTapCancel && onTapCancel(event, info);
4735 }
4736 else {
4737 onTap && onTap(event, info);
4738 }
4739 };
4740 function onPointerDown(event, info) {
4741 removePointerUp();
4742 cancelPointerEventListener.current = addPointerEvent(window, "pointerup", function (event, info) { return onPointerUp.current(event, info); });
4743 var element = ref.current;
4744 if (!element || isTapping.current)
4745 return;
4746 isTapping.current = true;
4747 onTapStart && onTapStart(event, info);
4748 if (controls && whileTap) {
4749 controls.startOverride(tapGesturePriority);
4750 }
4751 }
4752 usePointerEvent(ref, "pointerdown", hasTapListeners ? onPointerDown : undefined);
4753 useUnmountEffect(removePointerUp);
4754 }
4755
4756 var hoverPriority = getGesturePriority("whileHover");
4757 var filterTouch = function (listener) { return function (event, info) {
4758 if (isMouseEvent(event))
4759 listener(event, info);
4760 }; };
4761 /**
4762 *
4763 * @param props
4764 * @param ref
4765 * @internal
4766 */
4767 function useHoverGesture(_a, ref) {
4768 var whileHover = _a.whileHover, onHoverStart = _a.onHoverStart, onHoverEnd = _a.onHoverEnd, controls = _a.controls;
4769 if (whileHover && controls) {
4770 controls.setOverride(whileHover, hoverPriority);
4771 }
4772 usePointerEvent(ref, "pointerenter", filterTouch(function (event, info) {
4773 if (onHoverStart)
4774 onHoverStart(event, info);
4775 if (whileHover && controls) {
4776 controls.startOverride(hoverPriority);
4777 }
4778 }));
4779 usePointerEvent(ref, "pointerleave", filterTouch(function (event, info) {
4780 if (onHoverEnd)
4781 onHoverEnd(event, info);
4782 if (whileHover && controls) {
4783 controls.clearOverride(hoverPriority);
4784 }
4785 }));
4786 }
4787
4788 /**
4789 * Add pan and tap gesture recognition to an element.
4790 *
4791 * @param props - Gesture event handlers
4792 * @param ref - React `ref` containing a DOM `Element`
4793 * @public
4794 */
4795 function useGestures(props, ref) {
4796 usePanGesture(props, ref);
4797 useTapGesture(props, ref);
4798 useHoverGesture(props, ref);
4799 }
4800
4801 var makeRenderlessComponent = function (hook) { return function (props) {
4802 hook(props);
4803 return null;
4804 }; };
4805
4806 var gestureProps = [
4807 "onPan",
4808 "onPanStart",
4809 "onPanEnd",
4810 "onPanSessionStart",
4811 "onTap",
4812 "onTapStart",
4813 "onTapCancel",
4814 "whileTap",
4815 "whileHover",
4816 "onHoverStart",
4817 "onHoverEnd",
4818 ];
4819 var Gestures = {
4820 key: "gestures",
4821 shouldRender: function (props) {
4822 return gestureProps.some(function (key) { return props.hasOwnProperty(key); });
4823 },
4824 Component: makeRenderlessComponent(function (_a) {
4825 var innerRef = _a.innerRef, props = __rest(_a, ["innerRef"]);
4826 useGestures(props, innerRef);
4827 }),
4828 };
4829
4830 var isRefObject = function (ref) {
4831 return typeof ref === "object" && ref.hasOwnProperty("current");
4832 };
4833
4834 var noop = function (v) { return v; };
4835 /**
4836 * Don't block the default pointerdown behaviour of these elements.
4837 */
4838 var allowDefaultPointerDown = new Set(["INPUT", "TEXTAREA", "SELECT"]);
4839 var ComponentDragControls = /** @class */ (function () {
4840 function ComponentDragControls(_a) {
4841 var ref = _a.ref, values = _a.values, controls = _a.controls;
4842 /**
4843 * Track whether we're currently dragging.
4844 *
4845 * @internal
4846 */
4847 this.isDragging = false;
4848 /**
4849 * The current direction of drag, or `null` if both.
4850 *
4851 * @internal
4852 */
4853 this.currentDirection = null;
4854 /**
4855 * The permitted t/r/b/l boundaries of travel, in pixels.
4856 *
4857 * @internal
4858 */
4859 this.constraints = false;
4860 /**
4861 * A reference to the host component's latest props.
4862 *
4863 * @internal
4864 */
4865 this.props = {
4866 transformPagePoint: noop,
4867 };
4868 /**
4869 * References to the MotionValues used for tracking the current dragged point.
4870 *
4871 * @internal
4872 */
4873 this.point = {};
4874 /**
4875 * The origin point for the current drag gesture.
4876 *
4877 * @internal
4878 */
4879 this.origin = {
4880 x: motionValue(0),
4881 y: motionValue(0),
4882 };
4883 // This is a reference to the global drag gesture lock, ensuring only one component
4884 // can "capture" the drag of one or both axes.
4885 // TODO: Look into moving this into pansession?
4886 this.openGlobalLock = null;
4887 /**
4888 * @internal
4889 */
4890 this.panSession = null;
4891 /**
4892 * A reference to the previous constraints bounding box
4893 *
4894 * @internal
4895 */
4896 this.prevConstraintsBox = {
4897 width: 0,
4898 height: 0,
4899 x: 0,
4900 y: 0,
4901 };
4902 this.ref = ref;
4903 this.values = values;
4904 this.controls = controls;
4905 }
4906 /**
4907 * Start dragging the host component.
4908 *
4909 * @param event - The originating pointer event.
4910 * @param options -
4911 *
4912 * @public
4913 */
4914 ComponentDragControls.prototype.start = function (originEvent, _a) {
4915 var _this = this;
4916 var _b = (_a === void 0 ? {} : _a).snapToCursor, snapToCursor = _b === void 0 ? false : _b;
4917 snapToCursor && this.snapToCursor(originEvent);
4918 var onSessionStart = function (event) {
4919 // Prevent browser-specific behaviours like text selection or Chrome's image dragging.
4920 if (event.target &&
4921 !allowDefaultPointerDown.has(event.target.tagName)) {
4922 // On iOS it's important to not `preventDefault` the `touchstart`
4923 // event, as otherwise clicks won't fire inside the draggable element.
4924 if (!supportsTouchEvents()) {
4925 event.preventDefault();
4926 // Make sure input elements loose focus when we prevent the default.
4927 if (document.activeElement instanceof HTMLElement) {
4928 document.activeElement.blur();
4929 }
4930 }
4931 }
4932 // Initiate viewport scroll blocking on touch start. This is a very aggressive approach
4933 // which has come out of the difficulty in us being able to do this once a scroll gesture
4934 // has initiated in mobile browsers. This means if there's a horizontally-scrolling carousel
4935 // on a page we can't let a user scroll the page itself from it. Ideally what we'd do is
4936 // trigger this once we've got a scroll direction determined. This approach sort-of worked
4937 // but if the component was dragged too far in a single frame page scrolling would initiate.
4938 blockViewportScroll();
4939 // Stop any animations on both axis values immediately. This allows the user to throw and catch
4940 // the component.
4941 bothAxis(function (axis) {
4942 var axisPoint = _this.point[axis];
4943 axisPoint && axisPoint.stop();
4944 });
4945 };
4946 var onStart = function (event, info) {
4947 // If constraints are an element, resolve them again in case they've updated.
4948 if (_this.constraintsNeedResolution) {
4949 var _a = _this.props, dragConstraints = _a.dragConstraints, transformPagePoint_1 = _a.transformPagePoint;
4950 _this.constraints = calculateConstraintsFromDom(dragConstraints, _this.ref, _this.point, transformPagePoint_1);
4951 _this.applyConstraintsToPoint();
4952 }
4953 // Set point origin and stop any existing animations.
4954 bothAxis(function (axis) {
4955 var axisPoint = _this.point[axis];
4956 if (!axisPoint)
4957 return;
4958 _this.origin[axis].set(axisPoint.get());
4959 });
4960 // Attempt to grab the global drag gesture lock - maybe make this part of PanSession
4961 var _b = _this.props, drag = _b.drag, dragPropagation = _b.dragPropagation;
4962 if (drag && !dragPropagation) {
4963 if (_this.openGlobalLock)
4964 _this.openGlobalLock();
4965 _this.openGlobalLock = getGlobalLock(drag);
4966 if (!_this.openGlobalLock)
4967 return;
4968 }
4969 _this.isDragging = true;
4970 _this.currentDirection = null;
4971 var onDragStart = _this.props.onDragStart;
4972 onDragStart &&
4973 onDragStart(event, convertPanToDrag(info, _this.point));
4974 };
4975 var onMove = function (event, info) {
4976 var _a = _this.props, dragPropagation = _a.dragPropagation, dragDirectionLock = _a.dragDirectionLock;
4977 // If we didn't successfully receive the gesture lock, early return.
4978 if (!dragPropagation && !_this.openGlobalLock)
4979 return;
4980 var offset = info.offset;
4981 // Attempt to detect drag direction if directionLock is true
4982 if (dragDirectionLock && _this.currentDirection === null) {
4983 _this.currentDirection = getCurrentDirection(offset);
4984 // If we've successfully set a direction, notify listener
4985 if (_this.currentDirection !== null) {
4986 var onDirectionLock = _this.props.onDirectionLock;
4987 onDirectionLock && onDirectionLock(_this.currentDirection);
4988 }
4989 return;
4990 }
4991 _this.updatePoint("x", offset);
4992 _this.updatePoint("y", offset);
4993 var onDrag = _this.props.onDrag;
4994 onDrag && onDrag(event, convertPanToDrag(info, _this.point));
4995 };
4996 var onEnd = function (event, info) {
4997 _this.stop(event, info);
4998 };
4999 var transformPagePoint = this.props.transformPagePoint;
5000 this.panSession = new PanSession(originEvent, {
5001 onSessionStart: onSessionStart,
5002 onStart: onStart,
5003 onMove: onMove,
5004 onEnd: onEnd,
5005 }, { transformPagePoint: transformPagePoint });
5006 };
5007 ComponentDragControls.prototype.cancelDrag = function () {
5008 unblockViewportScroll();
5009 this.isDragging = false;
5010 this.panSession && this.panSession.end();
5011 this.panSession = null;
5012 if (!this.props.dragPropagation && this.openGlobalLock) {
5013 this.openGlobalLock();
5014 this.openGlobalLock = null;
5015 }
5016 };
5017 ComponentDragControls.prototype.stop = function (event, info) {
5018 var _a;
5019 (_a = this.panSession) === null || _a === void 0 ? void 0 : _a.end();
5020 this.panSession = null;
5021 var isDragging = this.isDragging;
5022 this.cancelDrag();
5023 if (!isDragging)
5024 return;
5025 var _b = this.props, dragMomentum = _b.dragMomentum, dragElastic = _b.dragElastic, onDragEnd = _b.onDragEnd;
5026 if (dragMomentum || dragElastic) {
5027 var velocity = info.velocity;
5028 this.animateDragEnd(velocity);
5029 }
5030 else {
5031 this.recordBoxInfo(this.constraints);
5032 }
5033 onDragEnd && onDragEnd(event, convertPanToDrag(info, this.point));
5034 };
5035 ComponentDragControls.prototype.recordBoxInfo = function (constraints) {
5036 if (constraints) {
5037 var right = constraints.right, left = constraints.left, bottom = constraints.bottom, top_1 = constraints.top;
5038 this.prevConstraintsBox.width = (right || 0) - (left || 0);
5039 this.prevConstraintsBox.height = (bottom || 0) - (top_1 || 0);
5040 }
5041 if (this.point.x)
5042 this.prevConstraintsBox.x = this.point.x.get();
5043 if (this.point.y)
5044 this.prevConstraintsBox.y = this.point.y.get();
5045 };
5046 ComponentDragControls.prototype.snapToCursor = function (event) {
5047 var _this = this;
5048 var transformPagePoint = this.props.transformPagePoint;
5049 var point = extractEventInfo(event).point;
5050 var boundingBox = getBoundingBox(this.ref, transformPagePoint);
5051 var center = {
5052 x: boundingBox.width / 2 + boundingBox.left + window.scrollX,
5053 y: boundingBox.height / 2 + boundingBox.top + window.scrollY,
5054 };
5055 var offset = {
5056 x: point.x - center.x,
5057 y: point.y - center.y,
5058 };
5059 bothAxis(function (axis) {
5060 var point = _this.point[axis];
5061 if (!point)
5062 return;
5063 _this.origin[axis].set(point.get());
5064 });
5065 this.updatePoint("x", offset);
5066 this.updatePoint("y", offset);
5067 };
5068 ComponentDragControls.prototype.setPoint = function (axis, value) {
5069 this.point[axis] = value;
5070 };
5071 ComponentDragControls.prototype.updatePoint = function (axis, offset) {
5072 var _a = this.props, drag = _a.drag, dragElastic = _a.dragElastic;
5073 var axisPoint = this.point[axis];
5074 // If we're not dragging this axis, do an early return.
5075 if (!shouldDrag(axis, drag, this.currentDirection) || !axisPoint)
5076 return;
5077 var current = applyConstraints(axis, this.origin[axis].get() + offset[axis], this.constraints, dragElastic);
5078 axisPoint.set(current);
5079 };
5080 ComponentDragControls.prototype.updateProps = function (_a) {
5081 var _this = this;
5082 var _b = _a.drag, drag = _b === void 0 ? false : _b, _c = _a.dragDirectionLock, dragDirectionLock = _c === void 0 ? false : _c, _d = _a.dragPropagation, dragPropagation = _d === void 0 ? false : _d, _e = _a.dragConstraints, dragConstraints = _e === void 0 ? false : _e, _f = _a.dragElastic, dragElastic = _f === void 0 ? true : _f, _g = _a.dragMomentum, dragMomentum = _g === void 0 ? true : _g, remainingProps = __rest(_a, ["drag", "dragDirectionLock", "dragPropagation", "dragConstraints", "dragElastic", "dragMomentum"]);
5083 this.props = __assign({ drag: drag,
5084 dragDirectionLock: dragDirectionLock,
5085 dragPropagation: dragPropagation,
5086 dragConstraints: dragConstraints,
5087 dragElastic: dragElastic,
5088 dragMomentum: dragMomentum }, remainingProps);
5089 var _dragValueX = remainingProps._dragValueX, _dragValueY = remainingProps._dragValueY, dragOriginX = remainingProps.dragOriginX, dragOriginY = remainingProps.dragOriginY;
5090 if (dragOriginX)
5091 this.origin.x = dragOriginX;
5092 if (dragOriginY)
5093 this.origin.y = dragOriginY;
5094 // Get the `MotionValue` for both draggable axes, or create them if they don't already
5095 // exist on this component.
5096 bothAxis(function (axis) {
5097 if (!shouldDrag(axis, drag, _this.currentDirection))
5098 return;
5099 var defaultValue = axis === "x" ? _dragValueX : _dragValueY;
5100 _this.setPoint(axis, defaultValue || _this.values.get(axis, 0));
5101 });
5102 // If `dragConstraints` is a React `ref`, we should resolve the constraints once the
5103 // component has rendered.
5104 this.constraintsNeedResolution = isRefObject(dragConstraints);
5105 this.constraints = this.constraintsNeedResolution
5106 ? this.constraints || false
5107 : dragConstraints;
5108 };
5109 ComponentDragControls.prototype.applyConstraintsToPoint = function (constraints) {
5110 var _this = this;
5111 if (constraints === void 0) { constraints = this.constraints; }
5112 return bothAxis(function (axis) {
5113 var axisPoint = _this.point[axis];
5114 axisPoint &&
5115 !axisPoint.isAnimating() &&
5116 applyConstraints(axis, axisPoint, constraints, 0);
5117 });
5118 };
5119 ComponentDragControls.prototype.animateDragEnd = function (velocity) {
5120 var _this = this;
5121 var _a = this.props, drag = _a.drag, dragMomentum = _a.dragMomentum, dragElastic = _a.dragElastic, dragTransition = _a.dragTransition, _dragValueX = _a._dragValueX, _dragValueY = _a._dragValueY, _dragTransitionControls = _a._dragTransitionControls;
5122 var momentumAnimations = bothAxis(function (axis) {
5123 var _a;
5124 if (!shouldDrag(axis, drag, _this.currentDirection)) {
5125 return;
5126 }
5127 var transition = _this.constraints
5128 ? getConstraints(axis, _this.constraints)
5129 : {};
5130 /**
5131 * Overdamp the boundary spring if `dragElastic` is disabled. There's still a frame
5132 * of spring animations so we should look into adding a disable spring option to `inertia`.
5133 * We could do something here where we affect the `bounceStiffness` and `bounceDamping`
5134 * using the value of `dragElastic`.
5135 */
5136 var bounceStiffness = dragElastic ? 200 : 1000000;
5137 var bounceDamping = dragElastic ? 40 : 10000000;
5138 var animationControls = _dragTransitionControls || _this.controls;
5139 var inertia = __assign(__assign({ type: "inertia", velocity: dragMomentum ? velocity[axis] : 0, bounceStiffness: bounceStiffness,
5140 bounceDamping: bounceDamping, timeConstant: 750, restDelta: 1 }, dragTransition), transition);
5141 var externalAxisMotionValue = axis === "x" ? _dragValueX : _dragValueY;
5142 // If we're not animating on an externally-provided `MotionValue` we can use the
5143 // component's animation controls which will handle interactions with whileHover (etc),
5144 // otherwise we just have to animate the `MotionValue` itself.
5145 return externalAxisMotionValue
5146 ? startAnimation(axis, externalAxisMotionValue, 0, inertia)
5147 : animationControls.start((_a = {},
5148 _a[axis] = 0,
5149 _a.transition = inertia,
5150 _a));
5151 });
5152 // Run all animations and then resolve the new drag constraints.
5153 return Promise.all(momentumAnimations).then(function () {
5154 _this.recordBoxInfo(_this.constraints);
5155 _this.scalePoint();
5156 var onDragTransitionEnd = _this.props.onDragTransitionEnd;
5157 onDragTransitionEnd && onDragTransitionEnd();
5158 });
5159 };
5160 ComponentDragControls.prototype.scalePoint = function () {
5161 var _this = this;
5162 var _a = this.props, dragConstraints = _a.dragConstraints, transformPagePoint = _a.transformPagePoint;
5163 if (!isRefObject(dragConstraints))
5164 return;
5165 var constraintsBox = getBoundingBox(dragConstraints, transformPagePoint);
5166 var draggableBox = getBoundingBox(this.ref, transformPagePoint);
5167 // Scale a point relative to the transformation of a constraints-providing element.
5168 var scaleAxisPoint = function (axis, dimension) {
5169 var pointToScale = _this.point[axis];
5170 if (!pointToScale)
5171 return;
5172 // Stop any current animations as they bug out if you resize during one
5173 if (pointToScale.isAnimating()) {
5174 pointToScale.stop();
5175 _this.recordBoxInfo();
5176 return;
5177 }
5178 // If the previous dimension was `0` (default), set `scale` to `1` to prevent
5179 // divide by zero errors.
5180 var scale = _this.prevConstraintsBox[dimension]
5181 ? (constraintsBox[dimension] - draggableBox[dimension]) /
5182 _this.prevConstraintsBox[dimension]
5183 : 1;
5184 pointToScale.set(_this.prevConstraintsBox[axis] * scale);
5185 };
5186 scaleAxisPoint("x", "width");
5187 scaleAxisPoint("y", "height");
5188 };
5189 ComponentDragControls.prototype.mount = function (element) {
5190 var _this = this;
5191 var stopPointerListener = addPointerEvent(element, "pointerdown", function (event) {
5192 var _a = _this.props, drag = _a.drag, _b = _a.dragListener, dragListener = _b === void 0 ? true : _b;
5193 drag && dragListener && _this.start(event);
5194 });
5195 var stopResizeListener = addDomEvent(window, "resize", function () {
5196 return _this.scalePoint();
5197 });
5198 if (this.constraintsNeedResolution) {
5199 var _a = this.props, dragConstraints = _a.dragConstraints, transformPagePoint = _a.transformPagePoint;
5200 var constraints = calculateConstraintsFromDom(dragConstraints, this.ref, this.point, transformPagePoint);
5201 this.applyConstraintsToPoint(constraints);
5202 this.recordBoxInfo(constraints);
5203 }
5204 else if (!this.isDragging && this.constraints) {
5205 this.applyConstraintsToPoint();
5206 }
5207 return function () {
5208 stopPointerListener && stopPointerListener();
5209 stopResizeListener && stopResizeListener();
5210 _this.cancelDrag();
5211 };
5212 };
5213 return ComponentDragControls;
5214 }());
5215 // Call a handler once for each axis
5216 function bothAxis(handler) {
5217 return [handler("x"), handler("y")];
5218 }
5219 function convertPanToDrag(info, point) {
5220 return __assign(__assign({}, info), { point: {
5221 x: point.x ? point.x.get() : 0,
5222 y: point.y ? point.y.get() : 0,
5223 } });
5224 }
5225 function getConstraints(axis, _a) {
5226 var top = _a.top, right = _a.right, bottom = _a.bottom, left = _a.left;
5227 if (axis === "x") {
5228 return { min: left, max: right };
5229 }
5230 else {
5231 return { min: top, max: bottom };
5232 }
5233 }
5234 function shouldDrag(direction, drag, currentDirection) {
5235 return ((drag === true || drag === direction) &&
5236 (currentDirection === null || currentDirection === direction));
5237 }
5238 /**
5239 * Based on an x/y offset determine the current drag direction. If both axis' offsets are lower
5240 * than the provided threshold, return `null`.
5241 *
5242 * @param offset - The x/y offset from origin.
5243 * @param lockThreshold - (Optional) - the minimum absolute offset before we can determine a drag direction.
5244 */
5245 function getCurrentDirection(offset, lockThreshold) {
5246 if (lockThreshold === void 0) { lockThreshold = 10; }
5247 var direction = null;
5248 if (Math.abs(offset.y) > lockThreshold) {
5249 direction = "y";
5250 }
5251 else if (Math.abs(offset.x) > lockThreshold) {
5252 direction = "x";
5253 }
5254 return direction;
5255 }
5256 /**
5257 * Takes a parent Element and a draggable Element and returns pixel-based drag constraints.
5258 *
5259 * @param constraintsRef
5260 * @param draggableRef
5261 */
5262 function calculateConstraintsFromDom(constraintsRef, draggableRef, point, transformPagePoint) {
5263 invariant(constraintsRef.current !== null && draggableRef.current !== null, "If `dragConstraints` is set as a React ref, that ref must be passed to another component's `ref` prop.");
5264 var parentBoundingBox = getBoundingBox(constraintsRef, transformPagePoint);
5265 var draggableBoundingBox = getBoundingBox(draggableRef, transformPagePoint);
5266 var left = parentBoundingBox.left -
5267 draggableBoundingBox.left +
5268 getCurrentOffset(point.x);
5269 var top = parentBoundingBox.top -
5270 draggableBoundingBox.top +
5271 getCurrentOffset(point.y);
5272 var right = parentBoundingBox.width - draggableBoundingBox.width + left;
5273 var bottom = parentBoundingBox.height - draggableBoundingBox.height + top;
5274 return { top: top, left: left, right: right, bottom: bottom };
5275 }
5276 function getBoundingBox(ref, transformPagePoint) {
5277 var rect = ref.current.getBoundingClientRect();
5278 var _a = transformPagePoint({
5279 x: rect.left,
5280 y: rect.top,
5281 }), left = _a.x, top = _a.y;
5282 var _b = transformPagePoint({
5283 x: rect.width,
5284 y: rect.height,
5285 }), width = _b.x, height = _b.y;
5286 return { left: left, top: top, width: width, height: height };
5287 }
5288 function getCurrentOffset(point) {
5289 return point ? point.get() : 0;
5290 }
5291 function applyConstraints(axis, value, constraints, dragElastic) {
5292 var constrainedValue = value instanceof MotionValue ? value.get() : value;
5293 if (!constraints) {
5294 return constrainedValue;
5295 }
5296 var _a = getConstraints(axis, constraints), min = _a.min, max = _a.max;
5297 if (min !== undefined && constrainedValue < min) {
5298 constrainedValue = dragElastic
5299 ? applyOverdrag(min, constrainedValue, dragElastic)
5300 : Math.max(min, constrainedValue);
5301 }
5302 else if (max !== undefined && constrainedValue > max) {
5303 constrainedValue = dragElastic
5304 ? applyOverdrag(max, constrainedValue, dragElastic)
5305 : Math.min(max, constrainedValue);
5306 }
5307 if (value instanceof MotionValue) {
5308 value.set(constrainedValue);
5309 }
5310 return constrainedValue;
5311 }
5312 function applyOverdrag(origin, current, dragElastic) {
5313 var dragFactor = typeof dragElastic === "number" ? dragElastic : 0.35;
5314 return mix(origin, current, dragFactor);
5315 }
5316
5317 /**
5318 * A hook that allows an element to be dragged.
5319 *
5320 * @param param
5321 * @param ref
5322 * @param values
5323 * @param controls
5324 *
5325 * @internal
5326 */
5327 function useDrag(props, ref, values, controls) {
5328 var groupDragControls = props.dragControls;
5329 var transformPagePoint = React.useContext(MotionPluginContext).transformPagePoint;
5330 var dragControls = useConstant(function () { return new ComponentDragControls({ ref: ref, values: values, controls: controls }); });
5331 dragControls.updateProps(__assign(__assign({}, props), { transformPagePoint: transformPagePoint }));
5332 React.useEffect(function () { return groupDragControls && groupDragControls.subscribe(dragControls); }, [dragControls]);
5333 React.useEffect(function () { return dragControls.mount(ref.current); }, []);
5334 }
5335
5336 var Drag = {
5337 key: "drag",
5338 shouldRender: function (props) { return !!props.drag; },
5339 Component: makeRenderlessComponent(function (_a) {
5340 var innerRef = _a.innerRef, values = _a.values, controls = _a.controls, props = __rest(_a, ["innerRef", "values", "controls"]);
5341 return useDrag(props, innerRef, values, controls);
5342 }),
5343 };
5344
5345 function isCSSVariable(value) {
5346 return typeof value === "string" && value.startsWith("var(--");
5347 }
5348 /**
5349 * Parse Framer's special CSS variable format into a CSS token and a fallback.
5350 *
5351 * ```
5352 * `var(--foo, #fff)` => [`--foo`, '#fff']
5353 * ```
5354 *
5355 * @param current
5356 */
5357 var cssVariableRegex = /var\((--[a-zA-Z0-9-_]+),? ?([a-zA-Z0-9 ()%#.,-]+)?\)/;
5358 function parseCSSVariable(current) {
5359 var match = cssVariableRegex.exec(current);
5360 if (!match)
5361 return [,];
5362 var token = match[1], fallback = match[2];
5363 return [token, fallback];
5364 }
5365 var maxDepth = 4;
5366 function getVariableValue(current, element, depth) {
5367 if (depth === void 0) { depth = 1; }
5368 invariant(depth <= maxDepth, "Max CSS variable fallback depth detected in property \"" + current + "\". This may indicate a circular fallback dependency.");
5369 var _a = parseCSSVariable(current), token = _a[0], fallback = _a[1];
5370 // No CSS variable detected
5371 if (!token)
5372 return;
5373 // Attempt to read this CSS variable off the element
5374 var resolved = window.getComputedStyle(element).getPropertyValue(token);
5375 if (resolved) {
5376 return resolved;
5377 }
5378 else if (isCSSVariable(fallback)) {
5379 // The fallback might itself be a CSS variable, in which case we attempt to resolve it too.
5380 return getVariableValue(fallback, element, depth + 1);
5381 }
5382 else {
5383 return fallback;
5384 }
5385 }
5386 /**
5387 * Resolve CSS variables from
5388 *
5389 * @internal
5390 */
5391 function resolveCSSVariables(values, ref, _a, transitionEnd) {
5392 var target = __rest(_a, []);
5393 var element = ref.current;
5394 if (!(element instanceof HTMLElement))
5395 return { target: target, transitionEnd: transitionEnd };
5396 // If `transitionEnd` isn't `undefined`, clone it. We could clone `target` and `transitionEnd`
5397 // only if they change but I think this reads clearer and this isn't a performance-critical path.
5398 if (transitionEnd) {
5399 transitionEnd = __assign({}, transitionEnd);
5400 }
5401 // Go through existing `MotionValue`s and ensure any existing CSS variables are resolved
5402 values.forEach(function (value) {
5403 var current = value.get();
5404 if (!isCSSVariable(current))
5405 return;
5406 var resolved = getVariableValue(current, element);
5407 if (resolved)
5408 value.set(resolved);
5409 });
5410 // Cycle through every target property and resolve CSS variables. Currently
5411 // we only read single-var properties like `var(--foo)`, not `calc(var(--foo) + 20px)`
5412 for (var key in target) {
5413 var current = target[key];
5414 if (!isCSSVariable(current))
5415 continue;
5416 var resolved = getVariableValue(current, element);
5417 if (!resolved)
5418 continue;
5419 // Clone target if it hasn't already been
5420 target[key] = resolved;
5421 // If the user hasn't already set this key on `transitionEnd`, set it to the unresolved
5422 // CSS variable. This will ensure that after the animation the component will reflect
5423 // changes in the value of the CSS variable.
5424 if (transitionEnd && transitionEnd[key] === undefined) {
5425 transitionEnd[key] = current;
5426 }
5427 }
5428 return { target: target, transitionEnd: transitionEnd };
5429 }
5430
5431 var positionalKeys = new Set([
5432 "width",
5433 "height",
5434 "top",
5435 "left",
5436 "right",
5437 "bottom",
5438 "x",
5439 "y",
5440 ]);
5441 var isPositionalKey = function (key) { return positionalKeys.has(key); };
5442 var hasPositionalKey = function (target) {
5443 return Object.keys(target).some(isPositionalKey);
5444 };
5445 var setAndResetVelocity = function (value, to) {
5446 // Looks odd but setting it twice doesn't render, it'll just
5447 // set both prev and current to the latest value
5448 value.set(to, false);
5449 value.set(to);
5450 };
5451 var isNumOrPxType = function (v) {
5452 return v === number || v === px;
5453 };
5454 var BoundingBoxDimension;
5455 (function (BoundingBoxDimension) {
5456 BoundingBoxDimension["width"] = "width";
5457 BoundingBoxDimension["height"] = "height";
5458 BoundingBoxDimension["left"] = "left";
5459 BoundingBoxDimension["right"] = "right";
5460 BoundingBoxDimension["top"] = "top";
5461 BoundingBoxDimension["bottom"] = "bottom";
5462 })(BoundingBoxDimension || (BoundingBoxDimension = {}));
5463 var getPosFromMatrix = function (matrix, pos) {
5464 return parseFloat(matrix.split(", ")[pos]);
5465 };
5466 var getTranslateFromMatrix = function (pos2, pos3) { return function (_bbox, _a) {
5467 var transform = _a.transform;
5468 if (transform === "none" || !transform)
5469 return 0;
5470 var matrix3d = transform.match(/^matrix3d\((.+)\)$/);
5471 if (matrix3d) {
5472 return getPosFromMatrix(matrix3d[1], pos3);
5473 }
5474 else {
5475 var matrix = transform.match(/^matrix\((.+)\)$/);
5476 return getPosFromMatrix(matrix[1], pos2);
5477 }
5478 }; };
5479 var transformKeys = new Set(["x", "y", "z"]);
5480 var nonTranslationalTransformKeys = transformProps.filter(function (key) { return !transformKeys.has(key); });
5481 function removeNonTranslationalTransform(values, elementStyler) {
5482 var removedTransforms = [];
5483 nonTranslationalTransformKeys.forEach(function (key) {
5484 var value = values.get(key);
5485 if (value !== undefined) {
5486 removedTransforms.push([key, value.get()]);
5487 value.set(key.startsWith("scale") ? 1 : 0);
5488 }
5489 });
5490 // Apply changes to element before measurement
5491 if (removedTransforms.length)
5492 elementStyler.render();
5493 return removedTransforms;
5494 }
5495 var positionalValues = {
5496 // Dimensions
5497 width: function (_a) {
5498 var width = _a.width;
5499 return width;
5500 },
5501 height: function (_a) {
5502 var height = _a.height;
5503 return height;
5504 },
5505 top: function (_bbox, _a) {
5506 var top = _a.top;
5507 return parseFloat(top);
5508 },
5509 left: function (_bbox, _a) {
5510 var left = _a.left;
5511 return parseFloat(left);
5512 },
5513 bottom: function (_a, _b) {
5514 var height = _a.height;
5515 var top = _b.top;
5516 return parseFloat(top) + height;
5517 },
5518 right: function (_a, _b) {
5519 var width = _a.width;
5520 var left = _b.left;
5521 return parseFloat(left) + width;
5522 },
5523 // Transform
5524 x: getTranslateFromMatrix(4, 13),
5525 y: getTranslateFromMatrix(5, 14),
5526 };
5527 var convertChangedValueTypes = function (target, values, element, elementStyler, changedKeys) {
5528 var originBbox = element.getBoundingClientRect();
5529 var elementComputedStyle = getComputedStyle(element);
5530 var display = elementComputedStyle.display, top = elementComputedStyle.top, left = elementComputedStyle.left, bottom = elementComputedStyle.bottom, right = elementComputedStyle.right, transform = elementComputedStyle.transform;
5531 var originComputedStyle = { top: top, left: left, bottom: bottom, right: right, transform: transform };
5532 // If the element is currently set to display: "none", make it visible before
5533 // measuring the target bounding box
5534 if (display === "none") {
5535 elementStyler.set("display", target.display || "block");
5536 }
5537 // Apply the latest values (as set in checkAndConvertChangedValueTypes)
5538 elementStyler.render();
5539 var targetBbox = element.getBoundingClientRect();
5540 changedKeys.forEach(function (key) {
5541 // Restore styles to their **calculated computed style**, not their actual
5542 // originally set style. This allows us to animate between equivalent pixel units.
5543 var value = values.get(key);
5544 setAndResetVelocity(value, positionalValues[key](originBbox, originComputedStyle));
5545 target[key] = positionalValues[key](targetBbox, elementComputedStyle);
5546 });
5547 return target;
5548 };
5549 var checkAndConvertChangedValueTypes = function (values, ref, target, transitionEnd) {
5550 if (transitionEnd === void 0) { transitionEnd = {}; }
5551 target = __assign({}, target);
5552 transitionEnd = __assign({}, transitionEnd);
5553 var element = ref.current;
5554 var elementStyler = index(element);
5555 var targetPositionalKeys = Object.keys(target).filter(isPositionalKey);
5556 // We want to remove any transform values that could affect the element's bounding box before
5557 // it's measured. We'll reapply these later.
5558 var removedTransformValues = [];
5559 var hasAttemptedToRemoveTransformValues = false;
5560 var changedValueTypeKeys = targetPositionalKeys.reduce(function (acc, key) {
5561 var value = values.get(key);
5562 if (!value)
5563 return acc;
5564 var from = value.get();
5565 var to = target[key];
5566 var fromType = getDimensionValueType(from);
5567 var toType;
5568 // TODO: The current implementation of this basically throws an error
5569 // if you try and do value conversion via keyframes. There's probably
5570 // a way of doing this but the performance implications would need greater scrutiny,
5571 // as it'd be doing multiple resize-remeasure operations.
5572 if (isKeyframesTarget(to)) {
5573 var numKeyframes = to.length;
5574 for (var i = to[0] === null ? 1 : 0; i < numKeyframes; i++) {
5575 if (!toType) {
5576 toType = getDimensionValueType(to[i]);
5577 invariant(toType === fromType ||
5578 (isNumOrPxType(fromType) &&
5579 isNumOrPxType(toType)), "Keyframes must be of the same dimension as the current value");
5580 }
5581 else {
5582 invariant(getDimensionValueType(to[i]) === toType, "All keyframes must be of the same type");
5583 }
5584 }
5585 }
5586 else {
5587 toType = getDimensionValueType(to);
5588 }
5589 if (fromType !== toType) {
5590 // If they're both just number or px, convert them both to numbers rather than
5591 // relying on resize/remeasure to convert (which is wasteful in this situation)
5592 if (isNumOrPxType(fromType) && isNumOrPxType(toType)) {
5593 var current = value.get();
5594 if (typeof current === "string") {
5595 value.set(parseFloat(current));
5596 }
5597 if (typeof to === "string") {
5598 target[key] = parseFloat(to);
5599 }
5600 else if (Array.isArray(to) && toType === px) {
5601 target[key] = to.map(parseFloat);
5602 }
5603 }
5604 else {
5605 // If we're going to do value conversion via DOM measurements, we first
5606 // need to remove non-positional transform values that could affect the bbox measurements.
5607 if (!hasAttemptedToRemoveTransformValues) {
5608 removedTransformValues = removeNonTranslationalTransform(values, elementStyler);
5609 hasAttemptedToRemoveTransformValues = true;
5610 }
5611 acc.push(key);
5612 transitionEnd[key] =
5613 transitionEnd[key] !== undefined
5614 ? transitionEnd[key]
5615 : target[key];
5616 setAndResetVelocity(value, to);
5617 }
5618 }
5619 return acc;
5620 }, []);
5621 if (changedValueTypeKeys.length) {
5622 var convertedTarget = convertChangedValueTypes(target, values, element, elementStyler, changedValueTypeKeys);
5623 // If we removed transform values, reapply them before the next render
5624 if (removedTransformValues.length) {
5625 removedTransformValues.forEach(function (_a) {
5626 var key = _a[0], value = _a[1];
5627 values.get(key).set(value);
5628 });
5629 }
5630 // Reapply original values
5631 elementStyler.render();
5632 return { target: convertedTarget, transitionEnd: transitionEnd };
5633 }
5634 else {
5635 return { target: target, transitionEnd: transitionEnd };
5636 }
5637 };
5638 /**
5639 * Convert value types for x/y/width/height/top/left/bottom/right
5640 *
5641 * Allows animation between `'auto'` -> `'100%'` or `0` -> `'calc(50% - 10vw)'`
5642 *
5643 * @param values
5644 * @param ref
5645 * @param target
5646 * @param transitionEnd
5647 * @internal
5648 */
5649 function unitConversion(values, ref, target, transitionEnd) {
5650 return hasPositionalKey(target)
5651 ? checkAndConvertChangedValueTypes(values, ref, target, transitionEnd)
5652 : { target: target, transitionEnd: transitionEnd };
5653 }
5654
5655 var parseDomVariant = function (values, ref) {
5656 return function (target, transitionEnd) {
5657 var resolved = resolveCSSVariables(values, ref, target, transitionEnd);
5658 target = resolved.target;
5659 transitionEnd = resolved.transitionEnd;
5660 return unitConversion(values, ref, target, transitionEnd);
5661 };
5662 };
5663
5664 function useForceUpdate() {
5665 var _a = React.useState(0), forcedRenderCount = _a[0], setForcedRenderCount = _a[1];
5666 return React.useCallback(function () { return setForcedRenderCount(forcedRenderCount + 1); }, [
5667 forcedRenderCount,
5668 ]);
5669 }
5670
5671 var SyncLayoutContext = React.createContext(null);
5672 /**
5673 * When layout changes happen asynchronously to their instigating render (ie when exiting
5674 * children of `AnimatePresence` are removed), `SyncLayout` can wrap parent and sibling
5675 * components that need to animate as a result of this layout change.
5676 *
5677 * @motion
5678 *
5679 * ```jsx
5680 * const MyComponent = ({ isVisible }) => {
5681 * return (
5682 * <SyncLayout>
5683 * <AnimatePresence>
5684 * {isVisible && (
5685 * <motion.div exit={{ opacity: 0 }} />
5686 * )}
5687 * </AnimatePresence>
5688 * <motion.div positionTransition />
5689 * </SyncLayout>
5690 * )
5691 * }
5692 * ```
5693 *
5694 * @internalremarks
5695 *
5696 * The way this component works is by memoising a function and passing it down via context.
5697 * The function, when called, updates the local state, which is used to invalidate the
5698 * memoisation cache. A new function is called, performing a synced re-render of components
5699 * that are using the SyncLayoutContext.
5700 *
5701 * @internal
5702 */
5703 var UnstableSyncLayout = function (_a) {
5704 var children = _a.children;
5705 var forceUpdate = useForceUpdate();
5706 return (React.createElement(SyncLayoutContext.Provider, { value: forceUpdate }, children));
5707 };
5708
5709 var _a$1;
5710 var StepName;
5711 (function (StepName) {
5712 StepName["Prepare"] = "prepare";
5713 StepName["Read"] = "read";
5714 StepName["Render"] = "render";
5715 })(StepName || (StepName = {}));
5716 var stepOrder = [StepName.Prepare, StepName.Read, StepName.Render];
5717 var jobs = stepOrder.reduce(function (acc, key) {
5718 acc[key] = [];
5719 return acc;
5720 }, {});
5721 var jobsNeedProcessing = false;
5722 function flushCallbackList(list) {
5723 var numJobs = list.length;
5724 for (var i = 0; i < numJobs; i++) {
5725 list[i]();
5726 }
5727 list.length = 0;
5728 }
5729 function flushAllJobs() {
5730 if (!jobsNeedProcessing)
5731 return;
5732 flushCallbackList(jobs.prepare);
5733 flushCallbackList(jobs.read);
5734 flushCallbackList(jobs.render);
5735 jobsNeedProcessing = false;
5736 }
5737 // Note: The approach of schedulng jobs during the render step is incompatible with concurrent mode
5738 // where multiple renders might happen without a DOM update. This would result in unneccessary batched
5739 // jobs. But this was already a problem with our previous approach to positionTransition.
5740 // Hopefully the React team offer a getSnapshotBeforeUpdate-esque hook and we can move to that.
5741 var createUseSyncEffect = function (stepName) { return function (callback) {
5742 if (!callback)
5743 return;
5744 jobsNeedProcessing = true;
5745 jobs[stepName].push(callback);
5746 }; };
5747 var layoutSync = (_a$1 = {},
5748 _a$1[StepName.Prepare] = createUseSyncEffect(StepName.Prepare),
5749 _a$1[StepName.Read] = createUseSyncEffect(StepName.Read),
5750 _a$1[StepName.Render] = createUseSyncEffect(StepName.Render),
5751 _a$1.flush = flushAllJobs,
5752 _a$1);
5753
5754 function isHTMLElement$1(element) {
5755 return element instanceof HTMLElement;
5756 }
5757
5758 var defaultLayoutTransition = {
5759 duration: 0.8,
5760 ease: [0.45, 0.05, 0.19, 1.0],
5761 };
5762 var defaultPositionTransition = underDampedSpring();
5763 function getDefaultLayoutTransition(isPositionOnly) {
5764 return isPositionOnly ? defaultPositionTransition : defaultLayoutTransition;
5765 }
5766 function isResolver(transition) {
5767 return typeof transition === "function";
5768 }
5769 var axisLabels = {
5770 x: {
5771 id: "x",
5772 size: "width",
5773 min: "left",
5774 max: "right",
5775 origin: "originX",
5776 },
5777 y: {
5778 id: "y",
5779 size: "height",
5780 min: "top",
5781 max: "bottom",
5782 origin: "originY",
5783 },
5784 };
5785 function centerOf(min, max) {
5786 return (min + max) / 2;
5787 }
5788 function calcAxisDelta(prev, next, names) {
5789 var _a;
5790 var sizeDelta = prev[names.size] - next[names.size];
5791 var origin = 0.5;
5792 // If the element has changed size we want to check whether either side is in
5793 // the same position before/after the layout transition. If so, we can anchor
5794 // the element to that position and only animate its size.
5795 if (sizeDelta) {
5796 if (prev[names.min] === next[names.min]) {
5797 origin = 0;
5798 }
5799 else if (prev[names.max] === next[names.max]) {
5800 origin = 1;
5801 }
5802 }
5803 var delta = (_a = {},
5804 _a[names.size] = sizeDelta,
5805 _a[names.origin] = origin,
5806 _a[names.id] =
5807 // Only measure a position delta if we haven't anchored to one side
5808 origin === 0.5
5809 ? centerOf(prev[names.min], prev[names.max]) -
5810 centerOf(next[names.min], next[names.max])
5811 : 0,
5812 _a);
5813 return delta;
5814 }
5815 function calcDelta(prev, next) {
5816 var delta = __assign(__assign({}, calcAxisDelta(prev, next, axisLabels.x)), calcAxisDelta(prev, next, axisLabels.y));
5817 return delta;
5818 }
5819 var offset = {
5820 getLayout: function (_a) {
5821 var offset = _a.offset;
5822 return offset;
5823 },
5824 measure: function (element) {
5825 var offsetLeft = element.offsetLeft, offsetTop = element.offsetTop, offsetWidth = element.offsetWidth, offsetHeight = element.offsetHeight;
5826 return {
5827 left: offsetLeft,
5828 top: offsetTop,
5829 right: offsetLeft + offsetWidth,
5830 bottom: offsetTop + offsetHeight,
5831 width: offsetWidth,
5832 height: offsetHeight,
5833 };
5834 },
5835 };
5836 var boundingBox = {
5837 getLayout: function (_a) {
5838 var boundingBox = _a.boundingBox;
5839 return boundingBox;
5840 },
5841 measure: function (element) {
5842 var _a = element.getBoundingClientRect(), left = _a.left, top = _a.top, width = _a.width, height = _a.height, right = _a.right, bottom = _a.bottom;
5843 return { left: left, top: top, width: width, height: height, right: right, bottom: bottom };
5844 },
5845 };
5846 function readPositionStyle(element) {
5847 return window.getComputedStyle(element).position;
5848 }
5849 function getLayoutType(prev, next, isPositionOnly) {
5850 return isPositionOnly && prev === next ? offset : boundingBox;
5851 }
5852 function isSizeKey(key) {
5853 return key === "width" || key === "height";
5854 }
5855 function getTransition(_a) {
5856 var layoutTransition = _a.layoutTransition, positionTransition = _a.positionTransition;
5857 return layoutTransition || positionTransition;
5858 }
5859 var LayoutAnimation = /** @class */ (function (_super) {
5860 __extends(LayoutAnimation, _super);
5861 function LayoutAnimation() {
5862 return _super !== null && _super.apply(this, arguments) || this;
5863 }
5864 // Measure the current state of the DOM before it's updated, and schedule checks to see
5865 // if it's changed as a result of a React render.
5866 LayoutAnimation.prototype.getSnapshotBeforeUpdate = function () {
5867 var _a = this.props, innerRef = _a.innerRef, positionTransition = _a.positionTransition, values = _a.values, controls = _a.controls;
5868 var element = innerRef.current;
5869 if (!isHTMLElement$1(element))
5870 return;
5871 var layoutTransition = getTransition(this.props);
5872 var isPositionOnly = !!positionTransition;
5873 var positionStyle = readPositionStyle(element);
5874 var prev = {
5875 offset: offset.measure(element),
5876 boundingBox: boundingBox.measure(element),
5877 };
5878 var transform;
5879 var next;
5880 var compare;
5881 // We split the unsetting, read and reapplication of the `transform` style prop into
5882 // different steps via useSyncEffect. Multiple components might all be doing the same
5883 // thing and by splitting these jobs and flushing them in batches we prevent layout thrashing.
5884 layoutSync.prepare(function () {
5885 // Unset the transform of all layoutTransition components so we can accurately measure
5886 // the target bounding box
5887 transform = element.style.transform;
5888 element.style.transform = "";
5889 });
5890 layoutSync.read(function () {
5891 // Read the target VisualInfo of all layoutTransition components
5892 next = {
5893 offset: offset.measure(element),
5894 boundingBox: boundingBox.measure(element),
5895 };
5896 var nextPosition = readPositionStyle(element);
5897 compare = getLayoutType(positionStyle, nextPosition, isPositionOnly);
5898 });
5899 layoutSync.render(function () {
5900 // Reverse the layout delta of all newly laid-out layoutTransition components into their
5901 // prev visual state and then animate them into their new one using transforms.
5902 var prevLayout = compare.getLayout(prev);
5903 var nextLayout = compare.getLayout(next);
5904 var delta = calcDelta(prevLayout, nextLayout);
5905 var hasAnyChanged = delta.x || delta.y || delta.width || delta.height;
5906 if (!hasAnyChanged) {
5907 // If layout hasn't changed, reapply the transform and get out of here.
5908 transform && (element.style.transform = transform);
5909 return;
5910 }
5911 index(element).set({
5912 originX: delta.originX,
5913 originY: delta.originY,
5914 });
5915 syncRenderSession.open();
5916 var target = {};
5917 var transition = {};
5918 var transitionDefinition = isResolver(layoutTransition)
5919 ? layoutTransition({ delta: delta })
5920 : layoutTransition;
5921 function makeTransition(layoutKey, transformKey, targetValue, visualOrigin) {
5922 // If this dimension hasn't changed, early return
5923 var deltaKey = isSizeKey(layoutKey) ? layoutKey : transformKey;
5924 if (!delta[deltaKey])
5925 return;
5926 var baseTransition = typeof transitionDefinition === "boolean"
5927 ? __assign({}, getDefaultLayoutTransition(isPositionOnly)) : transitionDefinition;
5928 var value = values.get(transformKey, targetValue);
5929 var velocity = value.getVelocity();
5930 transition[transformKey] = baseTransition[transformKey]
5931 ? __assign({}, baseTransition[transformKey]) : __assign({}, baseTransition);
5932 if (transition[transformKey].velocity === undefined) {
5933 transition[transformKey].velocity = velocity || 0;
5934 }
5935 // The target value of all transforms is the default value of that prop (ie x = 0, scaleX = 1)
5936 // This is because we're inverting the layout change with `transform` and then animating to `transform: none`
5937 target[transformKey] = targetValue;
5938 var offsetToApply = !isSizeKey(layoutKey) && compare === offset
5939 ? value.get()
5940 : 0;
5941 value.set(visualOrigin + offsetToApply);
5942 }
5943 makeTransition("left", "x", 0, delta.x);
5944 makeTransition("top", "y", 0, delta.y);
5945 if (!isPositionOnly) {
5946 makeTransition("width", "scaleX", 1, prev.boundingBox.width / next.boundingBox.width);
5947 makeTransition("height", "scaleY", 1, prev.boundingBox.height / next.boundingBox.height);
5948 }
5949 target.transition = transition;
5950 // Only start the transition if `transitionDefinition` isn't `false`. Otherwise we want
5951 // to leave the values in their newly-inverted state and let the user cope with the rest.
5952 transitionDefinition && controls.start(target);
5953 // Force a render to ensure there's no visual flickering
5954 syncRenderSession.flush();
5955 });
5956 return null;
5957 };
5958 LayoutAnimation.prototype.componentDidUpdate = function () {
5959 layoutSync.flush();
5960 };
5961 LayoutAnimation.prototype.render = function () {
5962 return null;
5963 };
5964 LayoutAnimation.contextType = SyncLayoutContext;
5965 return LayoutAnimation;
5966 }(React.Component));
5967 var Layout = {
5968 key: "layout",
5969 shouldRender: function (_a) {
5970 var positionTransition = _a.positionTransition, layoutTransition = _a.layoutTransition;
5971 invariant(!(positionTransition && layoutTransition), "Don't set both positionTransition and layoutTransition on the same component");
5972 return (typeof window !== "undefined" &&
5973 !!(positionTransition || layoutTransition));
5974 },
5975 Component: LayoutAnimation,
5976 };
5977
5978 /**
5979 * A list of all valid MotionProps
5980 *
5981 * @internalremarks
5982 * This doesn't throw if a `MotionProp` name is missing - it should.
5983 */
5984 var validMotionProps = new Set([
5985 "initial",
5986 "animate",
5987 "exit",
5988 "style",
5989 "variants",
5990 "transition",
5991 "transformTemplate",
5992 "transformValues",
5993 "custom",
5994 "inherit",
5995 "static",
5996 "positionTransition",
5997 "layoutTransition",
5998 "onAnimationStart",
5999 "onAnimationComplete",
6000 "onUpdate",
6001 "onDragStart",
6002 "onDrag",
6003 "onDragEnd",
6004 "onDirectionLock",
6005 "onDragTransitionEnd",
6006 "drag",
6007 "dragControls",
6008 "dragListener",
6009 "dragConstraints",
6010 "dragDirectionLock",
6011 "dragElastic",
6012 "dragMomentum",
6013 "dragPropagation",
6014 "dragTransition",
6015 "_dragValueX",
6016 "_dragValueY",
6017 "_dragTransitionControls",
6018 "dragOriginX",
6019 "dragOriginY",
6020 "onPan",
6021 "onPanStart",
6022 "onPanEnd",
6023 "onPanSessionStart",
6024 "onTap",
6025 "onTapStart",
6026 "onTapCancel",
6027 "whileHover",
6028 "whileTap",
6029 "onHoverEnd",
6030 "onHoverStart",
6031 ]);
6032 /**
6033 * Check whether a prop name is a valid `MotionProp` key.
6034 *
6035 * @param key - Name of the property to check
6036 * @returns `true` is key is a valid `MotionProp`.
6037 *
6038 * @public
6039 */
6040 function isValidMotionProp(key) {
6041 return validMotionProps.has(key);
6042 }
6043
6044 var AnimatePropType;
6045 (function (AnimatePropType) {
6046 AnimatePropType["Target"] = "Target";
6047 AnimatePropType["VariantLabel"] = "VariantLabel";
6048 AnimatePropType["AnimationSubscription"] = "AnimationSubscription";
6049 })(AnimatePropType || (AnimatePropType = {}));
6050
6051 function shallowCompare(next, prev) {
6052 if (prev === null)
6053 return false;
6054 var prevLength = prev.length;
6055 if (prevLength !== next.length)
6056 return false;
6057 for (var i = 0; i < prevLength; i++) {
6058 if (prev[i] !== next[i])
6059 return false;
6060 }
6061 return true;
6062 }
6063
6064 var hasUpdated = function (prev, next) {
6065 return (next !== undefined &&
6066 (Array.isArray(prev) && Array.isArray(next)
6067 ? !shallowCompare(next, prev)
6068 : prev !== next));
6069 };
6070 function targetWithoutTransition(_a, mergeTransitionEnd) {
6071 if (mergeTransitionEnd === void 0) { mergeTransitionEnd = false; }
6072 var transition = _a.transition, transitionEnd = _a.transitionEnd, target = __rest(_a, ["transition", "transitionEnd"]);
6073 return mergeTransitionEnd
6074 ? __assign(__assign({}, target), transitionEnd)
6075 : target;
6076 }
6077 /**
6078 * Handle the `animate` prop when its an object of values, ie:
6079 *
6080 * ```jsx
6081 * <motion.div animate={{ opacity: 1 }} />
6082 * ```
6083 *
6084 * @internalremarks
6085 * It might be worth consolidating this with `use-variants`
6086 *
6087 * ```jsx
6088 * <motion.div animate="visible" />
6089 * ```
6090 *
6091 * @param target
6092 * @param controls
6093 * @param values
6094 * @param transition
6095 *
6096 * @internal
6097 */
6098 function useAnimateProp(targetAndTransition, controls, values, defaultTransition) {
6099 var isInitialRender = React.useRef(true);
6100 var prevValues = React.useRef(null);
6101 if (!prevValues.current) {
6102 prevValues.current = targetWithoutTransition(targetAndTransition, true);
6103 }
6104 React.useEffect(function () {
6105 var targetToAnimate = {};
6106 // These are the values we're actually animating
6107 var animatingTarget = targetWithoutTransition(targetAndTransition);
6108 // This is the target as it'll be once transitionEnd values are applied
6109 var finalTarget = targetWithoutTransition(targetAndTransition, true);
6110 // Detect which values have changed between renders
6111 for (var key in animatingTarget) {
6112 // This value should animate on mount if this value doesn't already exist (wasn't
6113 // defined in `style` or `initial`) or if it does exist and it's already changed.
6114 var shouldAnimateOnMount = isInitialRender.current &&
6115 (!values.has(key) ||
6116 values.get(key).get() !== finalTarget[key]);
6117 // If this value has updated between renders or it's we're animating this value on mount,
6118 // add it to the animate target.
6119 var isValidValue = finalTarget[key] !== null;
6120 var valueHasUpdated = hasUpdated(prevValues.current[key], finalTarget[key]);
6121 if (isValidValue && (valueHasUpdated || shouldAnimateOnMount)) {
6122 targetToAnimate[key] = animatingTarget[key];
6123 }
6124 }
6125 isInitialRender.current = false;
6126 prevValues.current = __assign(__assign({}, prevValues.current), finalTarget);
6127 if (Object.keys(targetToAnimate).length) {
6128 controls.start(__assign(__assign({}, targetToAnimate), { transition: targetAndTransition.transition || defaultTransition, transitionEnd: targetAndTransition.transitionEnd }));
6129 }
6130 }, [targetAndTransition]);
6131 }
6132
6133 var labelsToArray = function (label) {
6134 if (!label) {
6135 return [];
6136 }
6137 if (Array.isArray(label)) {
6138 return label;
6139 }
6140 return [label];
6141 };
6142 var resolveVariantLabels = function (variant) {
6143 var unresolvedVariant = variant instanceof MotionValue ? variant.get() : variant;
6144 return Array.from(new Set(labelsToArray(unresolvedVariant)));
6145 };
6146 /**
6147 * Hooks in React sometimes accept a dependency array as their final argument. (ie useEffect/useMemo)
6148 * When values in this array change, React re-runs the dependency. However if the array
6149 * contains a variable number of items, React throws an error.
6150 */
6151 var asDependencyList = function (list) { return [
6152 list.join(","),
6153 ]; };
6154
6155 var hasVariantChanged = function (oldVariant, newVariant) {
6156 return oldVariant.join(",") !== newVariant.join(",");
6157 };
6158 /**
6159 * Handle variants and the `animate` prop when its set as variant labels.
6160 *
6161 * @param initial - Initial variant(s)
6162 * @param animate - Variant(s) to animate to
6163 * @param inherit - `true` is inheriting animations from parent
6164 * @param controls - Animation controls
6165 *
6166 * @internal
6167 */
6168 function useVariants(initial, animate, inherit, controls) {
6169 var targetVariants = resolveVariantLabels(animate);
6170 var context = React.useContext(MotionContext);
6171 var parentAlreadyMounted = context.hasMounted && context.hasMounted.current;
6172 var hasMounted = React.useRef(false);
6173 React.useEffect(function () {
6174 var shouldAnimate = false;
6175 if (inherit) {
6176 // If we're inheriting variant changes and the parent has already
6177 // mounted when this component loads, we need to manually trigger
6178 // this animation.
6179 shouldAnimate = !!parentAlreadyMounted;
6180 targetVariants = resolveVariantLabels(context.animate);
6181 }
6182 else {
6183 shouldAnimate =
6184 hasMounted.current ||
6185 hasVariantChanged(resolveVariantLabels(initial), targetVariants);
6186 }
6187 shouldAnimate && controls.start(targetVariants);
6188 hasMounted.current = true;
6189 }, asDependencyList(targetVariants));
6190 }
6191
6192 /**
6193 * `useAnimationGroupSubscription` allows a component to subscribe to an
6194 * externally-created `AnimationControls`, created by the `useAnimation` hook.
6195 *
6196 * @param animation
6197 * @param controls
6198 *
6199 * @internal
6200 */
6201 function useAnimationGroupSubscription(animation, controls) {
6202 var unsubscribe = React.useMemo(function () { return animation.subscribe(controls); }, [
6203 animation,
6204 ]);
6205 React.useEffect(function () { return function () {
6206 unsubscribe && unsubscribe();
6207 }; }, [unsubscribe]);
6208 }
6209
6210 var _a$2, _b;
6211 var AnimatePropComponents = (_a$2 = {},
6212 _a$2[AnimatePropType.Target] = makeRenderlessComponent(function (_a) {
6213 var animate = _a.animate, controls = _a.controls, values = _a.values, transition = _a.transition;
6214 return useAnimateProp(animate, controls, values, transition);
6215 }),
6216 _a$2[AnimatePropType.VariantLabel] = makeRenderlessComponent(function (_a) {
6217 var animate = _a.animate, _b = _a.inherit, inherit = _b === void 0 ? true : _b, controls = _a.controls, initial = _a.initial;
6218 return useVariants(initial, animate, inherit, controls);
6219 }),
6220 _a$2[AnimatePropType.AnimationSubscription] = makeRenderlessComponent(function (_a) {
6221 var animate = _a.animate, controls = _a.controls;
6222 return useAnimationGroupSubscription(animate, controls);
6223 }),
6224 _a$2);
6225 var isVariantLabel$1 = function (prop) {
6226 return Array.isArray(prop) || typeof prop === "string";
6227 };
6228 var isAnimationSubscription = function (_a) {
6229 var animate = _a.animate;
6230 return animate instanceof AnimationControls;
6231 };
6232 var animationProps = ["initial", "animate", "whileTap", "whileHover"];
6233 var animatePropTypeTests = (_b = {},
6234 _b[AnimatePropType.Target] = function (props) {
6235 return (props.animate !== undefined &&
6236 !isVariantLabel$1(props.animate) &&
6237 !isAnimationSubscription(props));
6238 },
6239 _b[AnimatePropType.VariantLabel] = function (props) {
6240 return (props.variants !== undefined ||
6241 animationProps.some(function (key) { return typeof props[key] === "string"; }));
6242 },
6243 _b[AnimatePropType.AnimationSubscription] = isAnimationSubscription,
6244 _b);
6245 var getAnimationComponent = function (props) {
6246 var animatePropType = undefined;
6247 for (var key in AnimatePropType) {
6248 if (animatePropTypeTests[key](props)) {
6249 animatePropType = key;
6250 }
6251 }
6252 return animatePropType ? AnimatePropComponents[animatePropType] : undefined;
6253 };
6254
6255 var Exit = {
6256 key: "exit",
6257 shouldRender: function (_a, _b) {
6258 var exit = _a.exit;
6259 var exitProps = _b.exitProps;
6260 var hasExitProps = !!exitProps;
6261 var hasExitAnimation = !!exit;
6262 invariant(!hasExitProps || (hasExitProps && hasExitAnimation), "No exit prop defined on a child of AnimatePresence.");
6263 return hasExitProps && hasExitAnimation;
6264 },
6265 Component: makeRenderlessComponent(function (props) {
6266 var animate = props.animate, controls = props.controls, parentContext = props.parentContext, exit = props.exit;
6267 var exitProps = parentContext.exitProps;
6268 var isPlayingExitAnimation = React.useRef(false);
6269 // This early return is more for types - it won't actually run because of the `shouldRender` above.
6270 if (!exitProps || !exit)
6271 return;
6272 var isExiting = exitProps.isExiting, custom = exitProps.custom, onExitComplete = exitProps.onExitComplete;
6273 React.useEffect(function () {
6274 if (isExiting) {
6275 if (!isPlayingExitAnimation.current && exit) {
6276 controls.setProps(__assign(__assign({}, props), { custom: custom !== undefined ? custom : props.custom }));
6277 controls.start(exit).then(onExitComplete);
6278 }
6279 isPlayingExitAnimation.current = true;
6280 }
6281 else if (isPlayingExitAnimation.current &&
6282 animate &&
6283 !(animate instanceof AnimationControls)) {
6284 controls.start(animate);
6285 }
6286 if (!isExiting) {
6287 isPlayingExitAnimation.current = false;
6288 }
6289 }, [isExiting]);
6290 }),
6291 };
6292
6293 var isPropValid = function (key) { return !isValidMotionProp(key); };
6294 /**
6295 * Emotion and Styled Components both allow users to pass through arbitrary props to their components
6296 * to dynamically generate CSS. They both use the `@emotion/is-prop-valid` package to determine which
6297 * of these should be passed to the underlying DOM node.
6298 *
6299 * However, when styling a Motion component `styled(motion.div)`, both packages pass through *all* props
6300 * as it's seen as an arbitrary component rather than a DOM node. Motion only allows arbitrary props
6301 * passed through the `custom` prop so it doesn't *need* the payload or computational overhead of
6302 * `@emotion/is-prop-valid`, however to fix this problem we need to use it.
6303 *
6304 * By making it an optionalDependency we can offer this functionality only in the situations where it's
6305 * actually required.
6306 */
6307 try {
6308 var emotionIsPropValid_1 = require("@emotion/is-prop-valid").default;
6309 isPropValid = function (key) {
6310 // Handle events explicitly as Emotion validates them all as true
6311 if (key.startsWith("on")) {
6312 return !isValidMotionProp(key);
6313 }
6314 else {
6315 return emotionIsPropValid_1(key);
6316 }
6317 };
6318 }
6319 catch (_a) {
6320 // We don't need to actually do anything here - the fallback is the existing `isPropValid`.
6321 }
6322 function filterValidProps(props) {
6323 var domProps = {};
6324 for (var key in props) {
6325 if (isPropValid(key)) {
6326 domProps[key] = props[key];
6327 }
6328 }
6329 return domProps;
6330 }
6331 var buildSVGProps = function (values, style) {
6332 var motionValueStyles = resolveCurrent(values);
6333 var props = buildSVGAttrs(motionValueStyles, undefined, undefined, undefined, undefined, false);
6334 props.style = __assign(__assign({}, style), props.style);
6335 return props;
6336 };
6337 var functionalityComponents = [Layout, Drag, Gestures, Exit];
6338 var numFunctionalityComponents = functionalityComponents.length;
6339 /**
6340 * Create a configuration for `motion` components that provides DOM-specific functionality.
6341 *
6342 * @internal
6343 */
6344 function createDomMotionConfig(Component) {
6345 var isDOM = typeof Component === "string";
6346 var isSVG = isDOM && svgElements.indexOf(Component) !== -1;
6347 return {
6348 renderComponent: function (ref, style, values, props, isStatic) {
6349 var forwardedProps = isDOM ? filterValidProps(props) : props;
6350 var staticVisualStyles = isSVG
6351 ? buildSVGProps(values, style)
6352 : { style: buildStyleAttr(values, style, isStatic) };
6353 return React.createElement(Component, __assign(__assign(__assign({}, forwardedProps), { ref: ref }), staticVisualStyles));
6354 },
6355 /**
6356 * loadFunctionalityComponents gets used by the `motion` component
6357 *
6358 * Each functionality component gets provided the `ref`, animation controls and the `MotionValuesMap`
6359 * generated for that component, as well as all the `props` passed to it by the user.
6360 *
6361 * The pattern used to determine whether to load and use each piece of functionality is
6362 * consistent (should render? Then push component) and could be used to extend functionality.
6363 *
6364 * By exposing a mutable piece of memory via an API like `extendMotionComponent` we could
6365 * allow users to add `FunctionalComponentDefinition`s. This would allow us to offer file size
6366 * reductions by shipping an entry point that doesn't load gesture and drag functionality, and
6367 * also offer a way for users to develop plugins/other functionality. Because these functionalities
6368 * are loaded as components, we can look into using Suspense for this purpose.
6369 *
6370 * For user-defined functionality we'd need to allow
6371 * 1) User-defined prop typing (extending `P`)
6372 * 2) User-defined "clean props" function that removes their plugin's props before being passed to the DOM.
6373 */
6374 loadFunctionalityComponents: function (ref, values, props, context, controls, inherit) {
6375 var activeComponents = [];
6376 // TODO: Consolidate Animation functionality loading strategy with other functionality components
6377 var Animation = getAnimationComponent(props);
6378 if (Animation) {
6379 activeComponents.push(React.createElement(Animation, { key: "animation", initial: props.initial, animate: props.animate, variants: props.variants, transition: props.transition, controls: controls, inherit: inherit, values: values }));
6380 }
6381 for (var i = 0; i < numFunctionalityComponents; i++) {
6382 var _a = functionalityComponents[i], shouldRender = _a.shouldRender, key = _a.key, Component_1 = _a.Component;
6383 if (shouldRender(props, context)) {
6384 activeComponents.push(React.createElement(Component_1, __assign({ key: key }, props, { parentContext: context, values: values, controls: controls, innerRef: ref })));
6385 }
6386 }
6387 return activeComponents;
6388 },
6389 getValueControlsConfig: function (ref, values) {
6390 return {
6391 values: values,
6392 readValueFromSource: function (key) {
6393 return index(ref.current).get(key);
6394 },
6395 // TODO: This is a good second source of plugins. This function contains the CSS variable
6396 // and unit conversion support. These functions share a common signature. We could make another
6397 // API for adding these.
6398 makeTargetAnimatable: parseDomVariant(values, ref),
6399 };
6400 },
6401 };
6402 }
6403
6404 var htmlMotionComponents = htmlElements.reduce(function (acc, Component) {
6405 var config = createDomMotionConfig(Component);
6406 // Suppress "Expression produces a union type that is too complex to represent" error
6407 // @ts-ignore
6408 acc[Component] = createMotionComponent(config);
6409 return acc;
6410 }, {});
6411 var svgMotionComponents = svgElements.reduce(function (acc, Component) {
6412 // Suppress "Expression produces a union type that is too complex to represent" error
6413 // @ts-ignore
6414 acc[Component] = createMotionComponent(createDomMotionConfig(Component));
6415 return acc;
6416 }, {});
6417 /**
6418 * HTML & SVG components, optimised for use with gestures and animation. These can be used as
6419 * drop-in replacements for any HTML & SVG component, all CSS & SVG properties are supported.
6420 *
6421 * @internalremarks
6422 *
6423 * I'd like to make it possible for these to be loaded "on demand" - to reduce bundle size by only
6424 * including HTML/SVG stylers, animation and/or gesture support when necessary.
6425 *
6426 * ```jsx
6427 * <motion.div animate={{ x: 100 }} />
6428 *
6429 * <motion.p animate={{ height: 200 }} />
6430 *
6431 * <svg><motion.circle r={10} animate={{ r: 20 }} /></svg>
6432 * ```
6433 *
6434 * @public
6435 */
6436 var motion = __assign(__assign({
6437 /**
6438 * Convert a custom React component into a `motion` component.
6439 *
6440 * It can also accept a string, to create [custom DOM elements](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements).
6441 *
6442 * ```jsx
6443 * const Component = React.forwardRef((props: Props, ref) => {
6444 * return <div ref={ref} />
6445 * })
6446 *
6447 * const MotionComponent = motion.custom<Props>(Component)
6448 * ```
6449 *
6450 * @param Component -
6451 */
6452 custom: function custom(Component) {
6453 return createMotionComponent(createDomMotionConfig(Component));
6454 } }, htmlMotionComponents), svgMotionComponents);
6455
6456 /**
6457 * Creates a `MotionValue` to track the state and velocity of a value.
6458 *
6459 * Usually, these are created automatically. For advanced use-cases, like use with `useTransform`, you can create `MotionValue`s externally and pass them into the animated component via the `style` prop.
6460 *
6461 * @library
6462 *
6463 * ```jsx
6464 * export function MyComponent() {
6465 * const scale = useMotionValue(1)
6466 *
6467 * return <Frame scale={scale} />
6468 * }
6469 * ```
6470 *
6471 * @motion
6472 *
6473 * ```jsx
6474 * export const MyComponent = () => {
6475 * const scale = useMotionValue(1)
6476 *
6477 * return <motion.div style={{ scale }} />
6478 * }
6479 * ```
6480 *
6481 * @param initial - The initial state.
6482 *
6483 * @public
6484 */
6485 function useMotionValue(initial) {
6486 return useConstant(function () { return motionValue(initial); });
6487 }
6488
6489 /**
6490 * If the provided value is a MotionValue, this returns the actual value, otherwise just the value itself
6491 *
6492 * TODO: Remove and move to library
6493 *
6494 * @internal
6495 */
6496 function unwrapMotionValue(value) {
6497 var unwrappedValue = value instanceof MotionValue ? value.get() : value;
6498 return isCustomValue(unwrappedValue)
6499 ? unwrappedValue.toValue()
6500 : unwrappedValue;
6501 }
6502
6503 var isCustomValueType = function (v) {
6504 return typeof v === "object" && v.mix;
6505 };
6506 var getMixer$1 = function (v) { return (isCustomValueType(v) ? v.mix : undefined); };
6507 function transform() {
6508 var args = [];
6509 for (var _i = 0; _i < arguments.length; _i++) {
6510 args[_i] = arguments[_i];
6511 }
6512 var useImmediate = !Array.isArray(args[0]);
6513 var argOffset = useImmediate ? 0 : -1;
6514 var inputValue = args[0 + argOffset];
6515 var inputRange = args[1 + argOffset];
6516 var outputRange = args[2 + argOffset];
6517 var options = args[3 + argOffset];
6518 var interpolator = interpolate(inputRange, outputRange, __assign({ mixer: getMixer$1(outputRange[0]) }, options));
6519 return useImmediate ? interpolator(inputValue) : interpolator;
6520 }
6521
6522 var isTransformer = function (v) {
6523 return typeof v === "function";
6524 };
6525 var noop$1 = function (v) { return v; };
6526 function useTransform(parent, customTransform, to, options) {
6527 var value = React.useRef(null);
6528 var comparitor = [parent];
6529 var transformer = noop$1;
6530 if (isTransformer(customTransform)) {
6531 transformer = customTransform;
6532 }
6533 else if (Array.isArray(to)) {
6534 var from = customTransform;
6535 transformer = transform(from, to, options);
6536 comparitor = [parent, from.join(","), to.join(",")];
6537 }
6538 return React.useMemo(function () {
6539 if (value.current)
6540 value.current.destroy();
6541 value.current = parent.addChild({ transformer: transformer });
6542 return value.current;
6543 }, comparitor);
6544 }
6545
6546 // Keep things reasonable and avoid scale: Infinity. In practise we might need
6547 // to add another value, opacity, that could interpolate scaleX/Y [0,0.01] => [0,1]
6548 // to simply hide content at unreasonable scales.
6549 var maxScale = 100000;
6550 var invertScale = function (scale) { return (scale > 0.001 ? 1 / scale : maxScale); };
6551 /**
6552 * Returns a `MotionValue` each for `scaleX` and `scaleY` that update with the inverse
6553 * of their respective parent scales.
6554 *
6555 * This is useful for undoing the distortion of content when scaling a parent component.
6556 *
6557 * By default, `useInvertedScale` will automatically fetch `scaleX` and `scaleY` from the nearest parent.
6558 * By passing other `MotionValue`s in as `useInvertedScale({ scaleX, scaleY })`, it will invert the output
6559 * of those instead.
6560 *
6561 * @motion
6562 *
6563 * ```jsx
6564 * const MyComponent = () => {
6565 * const { scaleX, scaleY } = useInvertedScale()
6566 * return <motion.div style={{ scaleX, scaleY }} />
6567 * }
6568 * ```
6569 *
6570 * @library
6571 *
6572 * ```jsx
6573 * function MyComponent() {
6574 * const { scaleX, scaleY } = useInvertedScale()
6575 * return <Frame scaleX={scaleX} scaleY={scaleY} />
6576 * }
6577 * ```
6578 *
6579 * @public
6580 */
6581 function useInvertedScale(scale) {
6582 var parentScaleX = useMotionValue(1);
6583 var parentScaleY = useMotionValue(1);
6584 var values = React.useContext(MotionContext).values;
6585 invariant(!!(scale || values), "If no scale values are provided, useInvertedScale must be used within a child of another motion component.");
6586 if (scale) {
6587 parentScaleX = scale.scaleX || parentScaleX;
6588 parentScaleY = scale.scaleY || parentScaleY;
6589 }
6590 else if (values) {
6591 parentScaleX = values.get("scaleX", 1);
6592 parentScaleY = values.get("scaleY", 1);
6593 }
6594 var scaleX = useTransform(parentScaleX, invertScale);
6595 var scaleY = useTransform(parentScaleY, invertScale);
6596 return { scaleX: scaleX, scaleY: scaleY };
6597 }
6598
6599 function useOnChange(value, callback) {
6600 React.useEffect(function () { return (isMotionValue(value) ? value.onChange(callback) : undefined); }, [value]);
6601 }
6602
6603 /**
6604 * Creates a `MotionValue` that, when `set`, will use a spring animation to animate to its new state.
6605 *
6606 * It can either work as a stand-alone `MotionValue` by initialising it with a value, or as a subscriber
6607 * to another `MotionValue`.
6608 *
6609 * @remarks
6610 *
6611 * ```jsx
6612 * const x = useSpring(0, { stiffness: 300 })
6613 * const y = useSpring(x, { damping: 10 })
6614 * ```
6615 *
6616 * @param inputValue - `MotionValue` or number. If provided a `MotionValue`, when the input `MotionValue` changes, the created `MotionValue` will spring towards that value.
6617 * @param springConfig - Configuration options for the spring.
6618 * @returns `MotionValue`
6619 *
6620 * @public
6621 */
6622 function useSpring(source, config) {
6623 if (config === void 0) { config = {}; }
6624 var activeSpringAnimation = React.useRef(null);
6625 var value = useMotionValue(isMotionValue(source) ? source.get() : source);
6626 React.useMemo(function () {
6627 return value.attach(function (v, set) {
6628 if (activeSpringAnimation.current) {
6629 activeSpringAnimation.current.stop();
6630 }
6631 activeSpringAnimation.current = vectorSpring(__assign({ from: value.get(), to: v, velocity: value.getVelocity() }, config)).start(set);
6632 return value.get();
6633 });
6634 }, Object.values(config));
6635 useOnChange(source, function (v) { return value.set(parseFloat(v)); });
6636 return value;
6637 }
6638
6639 var scrollX = motionValue(0);
6640 var scrollY = motionValue(0);
6641 var scrollXProgress = motionValue(0);
6642 var scrollYProgress = motionValue(0);
6643 var setProgress = function (offset, maxOffset, value) {
6644 value.set(!maxOffset || !offset ? 0 : offset / maxOffset);
6645 };
6646 var hasEventListener = false;
6647 var addScrollListener = function () {
6648 hasEventListener = true;
6649 if (typeof window === "undefined")
6650 return;
6651 var updateScrollValues = function () {
6652 var xOffset = window.pageXOffset;
6653 var yOffset = window.pageYOffset;
6654 // Set absolute positions
6655 scrollX.set(xOffset);
6656 scrollY.set(yOffset);
6657 // Set 0-1 progress
6658 setProgress(xOffset, document.body.clientWidth - window.innerWidth, scrollXProgress);
6659 setProgress(yOffset, document.body.clientHeight - window.innerHeight, scrollYProgress);
6660 };
6661 updateScrollValues();
6662 window.addEventListener("resize", updateScrollValues);
6663 window.addEventListener("scroll", updateScrollValues, { passive: true });
6664 };
6665 var viewportMotionValues = {
6666 scrollX: scrollX,
6667 scrollY: scrollY,
6668 scrollXProgress: scrollXProgress,
6669 scrollYProgress: scrollYProgress,
6670 };
6671 /**
6672 * Provides `MotionValue`s that update when the viewport scrolls:
6673 *
6674 * - `scrollX` — Horizontal scroll distance in pixels.
6675 * - `scrollY` — Vertical scroll distance in pixels.
6676 * - `scrollXProgress` — Horizontal scroll progress between `0` and `1`.
6677 * - `scrollYProgress` — Vertical scroll progress between `0` and `1`.
6678 *
6679 * **Note:** If the returned scroll `MotionValue`s don't seem to be updating,
6680 * double check if the `body` tag styles are set to `width: 100%; height: 100%` or
6681 * similar, as this can break accurate measurement of viewport scroll.
6682 *
6683 * @library
6684 *
6685 * ```jsx
6686 * import * as React from "react"
6687 * import {
6688 * Frame,
6689 * useViewportScroll,
6690 * useTransform
6691 * } from "framer"
6692 *
6693 * export function MyComponent() {
6694 * const { scrollYProgress } = useViewportScroll()
6695 * return <Frame scaleX={scrollYProgress} />
6696 * }
6697 * ```
6698 *
6699 * @motion
6700 *
6701 * ```jsx
6702 * export const MyComponent = () => {
6703 * const { scrollYProgress } = useViewportScroll()
6704 * return <motion.div style={{ scaleX: scrollYProgress }} />
6705 * }
6706 * ```
6707 *
6708 * @internalremarks
6709 * This isn't technically a hook yet, but in the future it might be nice
6710 * to accept refs to elements and add scroll listeners to those, which
6711 * may involve the use of lifecycle.
6712 *
6713 * @public
6714 */
6715 function useViewportScroll() {
6716 if (!hasEventListener) {
6717 addScrollListener();
6718 }
6719 return viewportMotionValues;
6720 }
6721
6722 /**
6723 * Creates `AnimationControls`, which can be used to manually start, stop
6724 * and sequence animations on one or more components.
6725 *
6726 * The returned `AnimationControls` should be passed to the `animate` property
6727 * of the components you want to animate.
6728 *
6729 * These components can then be animated with the `start` method.
6730 *
6731 * @library
6732 *
6733 * ```jsx
6734 * import * as React from 'react'
6735 * import { Frame, useAnimation } from 'framer'
6736 *
6737 * export function MyComponent(props) {
6738 * const controls = useAnimation()
6739 *
6740 * controls.start({
6741 * x: 100,
6742 * transition: { duration: 0.5 },
6743 * })
6744 *
6745 * return <Frame animate={controls} />
6746 * }
6747 * ```
6748 *
6749 * @motion
6750 *
6751 * ```jsx
6752 * import * as React from 'react'
6753 * import { motion, useAnimation } from 'framer-motion'
6754 *
6755 * export function MyComponent(props) {
6756 * const controls = useAnimation()
6757 *
6758 * controls.start({
6759 * x: 100,
6760 * transition: { duration: 0.5 },
6761 * })
6762 *
6763 * return <motion.div animate={controls} />
6764 * }
6765 * ```
6766 *
6767 * @returns Animation controller with `start` and `stop` methods
6768 *
6769 * @public
6770 */
6771 function useAnimation() {
6772 var animationControls = useConstant(function () { return new AnimationControls(); });
6773 React.useEffect(function () {
6774 animationControls.mount();
6775 return function () { return animationControls.unmount(); };
6776 }, []);
6777 return animationControls;
6778 }
6779
6780 /**
6781 * Experimental API.
6782 *
6783 * Makes an animated version of `useState`.
6784 *
6785 * @remarks
6786 *
6787 * When the returned state setter is called, values will be animated to their new target.
6788 *
6789 * This allows the animation of arbitrary React components.
6790 *
6791 * **Note:** When animating DOM components, it's always preferable to use the `animate` prop, as Framer
6792 * will bypass React's rendering cycle with one optimised for 60fps motion. This Hook is specifically
6793 * for animating props on arbitrary React components, or for animating text content.
6794 *
6795 * ```jsx
6796 * const [state, setState] = useAnimatedState({ percentage: 0 })
6797 *
6798 * return (
6799 * <Graph
6800 * percentage={state.percentage}
6801 * onTap={() => setState({ percentage: 50 })}
6802 * />
6803 * )
6804 * ```
6805 *
6806 * @internalremarks
6807 *
6808 * TODO:
6809 * - Make hook accept a typed version of Target that accepts any value (not just DOM values)
6810 * - Allow hook to accept single values. ie useAnimatedState(0)
6811 * - Allow providing MotionValues via initialState.
6812 *
6813 * @beta
6814 */
6815 function useAnimatedState(initialState) {
6816 var _a = React.useState(initialState), animationState = _a[0], onUpdate = _a[1];
6817 var config = useConstant(function () { return ({ onUpdate: onUpdate }); });
6818 var values = useMotionValues(config);
6819 var controls = useValueAnimationControls({
6820 values: values,
6821 readValueFromSource: function (key) { return animationState[key]; },
6822 }, {}, false);
6823 var startAnimation = useConstant(function () { return function (animationDefinition) {
6824 return controls.start(animationDefinition);
6825 }; });
6826 React.useEffect(function () {
6827 values.mount();
6828 return function () { return values.unmount(); };
6829 }, []);
6830 return [animationState, startAnimation];
6831 }
6832
6833 /**
6834 * Cycles through a series of visual properties. Can be used to toggle between or cycle through animations. It works similar to `useState` in React. It is provided an initial array of possible states, and returns an array of two arguments.
6835 *
6836 * @library
6837 *
6838 * ```jsx
6839 * import * as React from "react"
6840 * import { Frame, useCycle } from "framer"
6841 *
6842 * export function MyComponent() {
6843 * const [x, cycleX] = useCycle(0, 50, 100)
6844 *
6845 * return (
6846 * <Frame
6847 * animate={{ x: x }}
6848 * onTap={() => cycleX()}
6849 * />
6850 * )
6851 * }
6852 * ```
6853 *
6854 * @motion
6855 *
6856 * An index value can be passed to the returned `cycle` function to cycle to a specific index.
6857 *
6858 * ```jsx
6859 * import * as React from "react"
6860 * import { motion, useCycle } from "framer-motion"
6861 *
6862 * export const MyComponent = () => {
6863 * const [x, cycleX] = useCycle(0, 50, 100)
6864 *
6865 * return (
6866 * <motion.div
6867 * animate={{ x: x }}
6868 * onTap={() => cycleX()}
6869 * />
6870 * )
6871 * }
6872 * ```
6873 *
6874 * @param items - items to cycle through
6875 * @returns [currentState, cycleState]
6876 *
6877 * @public
6878 */
6879 function useCycle() {
6880 var items = [];
6881 for (var _i = 0; _i < arguments.length; _i++) {
6882 items[_i] = arguments[_i];
6883 }
6884 // TODO: After Framer X beta, remove this warning
6885 warning(items.length > 1, "useCycle syntax has changed. `useCycle([0, 1, 2])` becomes `useCycle(0, 1, 2)`");
6886 var index = React.useRef(0);
6887 var _a = React.useState(items[index.current]), item = _a[0], setItem = _a[1];
6888 return [
6889 item,
6890 function (next) {
6891 index.current =
6892 typeof next !== "number"
6893 ? wrap$1(0, items.length, index.current + 1)
6894 : next;
6895 setItem(items[index.current]);
6896 },
6897 ];
6898 }
6899
6900 /**
6901 * Can manually trigger a drag gesture on one or more `drag`-enabled `motion` components.
6902 *
6903 * @library
6904 *
6905 * ```jsx
6906 * const dragControls = useDragControls()
6907 *
6908 * function startDrag(event) {
6909 * dragControls.start(event, { snapToCursor: true })
6910 * }
6911 *
6912 * return (
6913 * <>
6914 * <Frame onTapStart={startDrag} />
6915 * <Frame drag="x" dragControls={dragControls} />
6916 * </>
6917 * )
6918 * ```
6919 *
6920 * @motion
6921 *
6922 * ```jsx
6923 * const dragControls = useDragControls()
6924 *
6925 * function startDrag(event) {
6926 * dragControls.start(event, { snapToCursor: true })
6927 * }
6928 *
6929 * return (
6930 * <>
6931 * <div onMouseDown={startDrag} />
6932 * <motion.div drag="x" dragControls={dragControls} />
6933 * </>
6934 * )
6935 * ```
6936 *
6937 * @public
6938 */
6939 var DragControls = /** @class */ (function () {
6940 function DragControls() {
6941 this.componentControls = new Set();
6942 }
6943 /**
6944 * Subscribe a component's internal `ComponentDragControls` to the user-facing API.
6945 *
6946 * @internal
6947 */
6948 DragControls.prototype.subscribe = function (controls) {
6949 var _this = this;
6950 this.componentControls.add(controls);
6951 return function () { return _this.componentControls.delete(controls); };
6952 };
6953 /**
6954 * Start a drag gesture on every `motion` component that has this set of drag controls
6955 * passed into it via the `dragControls` prop.
6956 *
6957 * ```jsx
6958 * dragControls.start(e, {
6959 * snapToCursor: true
6960 * })
6961 * ```
6962 *
6963 * @param event - A mouse/touch/pointer event.
6964 * @param options - Options
6965 *
6966 * @public
6967 */
6968 DragControls.prototype.start = function (event, options) {
6969 this.componentControls.forEach(function (controls) {
6970 controls.start(event.nativeEvent || event, options);
6971 });
6972 };
6973 return DragControls;
6974 }());
6975 var createDragControls = function () { return new DragControls(); };
6976 /**
6977 * Usually, dragging is initiated by pressing down on a `motion` component with a `drag` prop
6978 * and moving it. For some use-cases, for instance clicking at an arbitrary point on a video scrubber, we
6979 * might want to initiate that dragging from a different component than the draggable one.
6980 *
6981 * By creating a `dragControls` using the `useDragControls` hook, we can pass this into
6982 * the draggable component's `dragControls` prop. It exposes a `start` method
6983 * that can start dragging from pointer events on other components.
6984 *
6985 * @library
6986 *
6987 * ```jsx
6988 * const dragControls = useDragControls()
6989 *
6990 * function startDrag(event) {
6991 * dragControls.start(event, { snapToCursor: true })
6992 * }
6993 *
6994 * return (
6995 * <>
6996 * <Frame onTapStart={startDrag} />
6997 * <Frame drag="x" dragControls={dragControls} />
6998 * </>
6999 * )
7000 * ```
7001 *
7002 * @motion
7003 *
7004 * ```jsx
7005 * const dragControls = useDragControls()
7006 *
7007 * function startDrag(event) {
7008 * dragControls.start(event, { snapToCursor: true })
7009 * }
7010 *
7011 * return (
7012 * <>
7013 * <div onMouseDown={startDrag} />
7014 * <motion.div drag="x" dragControls={dragControls} />
7015 * </>
7016 * )
7017 * ```
7018 *
7019 * @public
7020 */
7021 function useDragControls() {
7022 return useConstant(createDragControls);
7023 }
7024
7025 var PresenceChild = function (_a) {
7026 var children = _a.children, exitProps = _a.exitProps;
7027 var context = React.useContext(MotionContext);
7028 // Create a new `value` in all instances to ensure `motion` children re-render
7029 // and detect any layout changes that might have occurred.
7030 context = __assign(__assign({}, context), { exitProps: exitProps || {} });
7031 return (React.createElement(MotionContext.Provider, { value: context }, children));
7032 };
7033 function getChildKey(child) {
7034 return child.key || "";
7035 }
7036 function updateChildLookup(children, allChildren) {
7037 var seenChildren = new Set() ;
7038 children.forEach(function (child) {
7039 var key = getChildKey(child);
7040 if ( seenChildren) {
7041 if (seenChildren.has(key)) {
7042 console.warn("Children of AnimatePresence require unique keys. \"" + key + "\" is a duplicate.");
7043 }
7044 seenChildren.add(key);
7045 }
7046 allChildren.set(key, child);
7047 });
7048 }
7049 function onlyElements(children) {
7050 var filtered = [];
7051 // We use forEach here instead of map as map mutates the component key by preprending `.$`
7052 React.Children.forEach(children, function (child) {
7053 if (React.isValidElement(child))
7054 filtered.push(child);
7055 });
7056 return filtered;
7057 }
7058 /**
7059 * The `AnimatePresence` component enables the use of the `exit` prop to animate components
7060 * when they're removed from the component tree.
7061 *
7062 * When adding/removing more than a single child component, every component
7063 * **must** be given a unique `key` prop.
7064 *
7065 * You can propagate exit animations throughout a tree by using variants.
7066 *
7067 * @library
7068 *
7069 * You can use any component(s) within `AnimatePresence`, but the first `Frame` in each should
7070 * have an `exit` property defined.
7071 *
7072 * ```jsx
7073 * import { Frame, AnimatePresence } from 'framer'
7074 *
7075 * // As items are added and removed from `items`
7076 * export function Items({ items }) {
7077 * return (
7078 * <AnimatePresence>
7079 * {items.map(item => (
7080 * <Frame
7081 * key={item.id}
7082 * initial={{ opacity: 0 }}
7083 * animate={{ opacity: 1 }}
7084 * exit={{ opacity: 0 }}
7085 * />
7086 * ))}
7087 * </AnimatePresence>
7088 * )
7089 * }
7090 * ```
7091 *
7092 * @motion
7093 *
7094 * You can use any component(s) within `AnimatePresence`, but the first `motion` component in each should
7095 * have an `exit` property defined.
7096 *
7097 * ```jsx
7098 * import { motion, AnimatePresence } from 'framer-motion'
7099 *
7100 * export const Items = ({ items }) => (
7101 * <AnimatePresence>
7102 * {items.map(item => (
7103 * <motion.div
7104 * key={item.id}
7105 * initial={{ opacity: 0 }}
7106 * animate={{ opacity: 1 }}
7107 * exit={{ opacity: 0 }}
7108 * />
7109 * ))}
7110 * </AnimatePresence>
7111 * )
7112 * ```
7113 *
7114 * @public
7115 */
7116 var AnimatePresence = function (_a) {
7117 var children = _a.children, custom = _a.custom, _b = _a.initial, initial = _b === void 0 ? true : _b, onExitComplete = _a.onExitComplete, exitBeforeEnter = _a.exitBeforeEnter;
7118 // We want to force a re-render once all exiting animations have finished. We
7119 // either use a local forceUpdate function, or one from a parent context if it exists.
7120 var localForceUpdate = useForceUpdate();
7121 var contextForceUpdate = React.useContext(SyncLayoutContext);
7122 var forceUpdate = contextForceUpdate || localForceUpdate;
7123 var isInitialRender = React.useRef(true);
7124 // Filter out any children that aren't ReactElements. We can only track ReactElements with a props.key
7125 var filteredChildren = onlyElements(children);
7126 // Keep a living record of the children we're actually rendering so we
7127 // can diff to figure out which are entering and exiting
7128 var presentChildren = React.useRef(filteredChildren);
7129 // A lookup table to quickly reference components by key
7130 var allChildren = React.useRef(new Map())
7131 .current;
7132 // A living record of all currently exiting components.
7133 var exiting = React.useRef(new Set()).current;
7134 updateChildLookup(filteredChildren, allChildren);
7135 // If this is the initial component render, just deal with logic surrounding whether
7136 // we play onMount animations or not.
7137 if (isInitialRender.current) {
7138 isInitialRender.current = false;
7139 return (React.createElement(React.Fragment, null, filteredChildren.map(function (child) { return (React.createElement(PresenceChild, { key: getChildKey(child), exitProps: initial ? undefined : { initial: false } }, child)); })));
7140 }
7141 // If this is a subsequent render, deal with entering and exiting children
7142 var childrenToRender = __spreadArrays(filteredChildren);
7143 // Diff the keys of the currently-present and target children to update our
7144 // exiting list.
7145 var presentKeys = presentChildren.current.map(getChildKey);
7146 var targetKeys = filteredChildren.map(getChildKey);
7147 // Diff the present children with our target children and mark those that are exiting
7148 var numPresent = presentKeys.length;
7149 for (var i = 0; i < numPresent; i++) {
7150 var key = presentKeys[i];
7151 if (targetKeys.indexOf(key) === -1) {
7152 exiting.add(key);
7153 }
7154 else {
7155 // In case this key has re-entered, remove from the exiting list
7156 exiting.delete(key);
7157 }
7158 }
7159 // If we currently have exiting children, and we're deferring rendering incoming children
7160 // until after all current children have exiting, empty the childrenToRender array
7161 if (exitBeforeEnter && exiting.size) {
7162 childrenToRender = [];
7163 }
7164 // Loop through all currently exiting components and clone them to overwrite `animate`
7165 // with any `exit` prop they might have defined.
7166 exiting.forEach(function (key) {
7167 // If this component is actually entering again, early return
7168 if (targetKeys.indexOf(key) !== -1)
7169 return;
7170 var child = allChildren.get(key);
7171 if (!child)
7172 return;
7173 var insertionIndex = presentKeys.indexOf(key);
7174 var onExit = function () {
7175 exiting.delete(key);
7176 // Remove this child from the present children
7177 var removeIndex = presentChildren.current.findIndex(function (child) { return child.key === key; });
7178 presentChildren.current.splice(removeIndex, 1);
7179 // Defer re-rendering until all exiting children have indeed left
7180 if (!exiting.size) {
7181 presentChildren.current = filteredChildren;
7182 forceUpdate();
7183 onExitComplete && onExitComplete();
7184 }
7185 };
7186 var exitProps = {
7187 custom: custom,
7188 isExiting: true,
7189 onExitComplete: onExit,
7190 };
7191 childrenToRender.splice(insertionIndex, 0, React.createElement(PresenceChild, { key: getChildKey(child), exitProps: exitProps }, child));
7192 });
7193 // Add `MotionContext` even to children that don't need it to ensure we're rendering
7194 // the same tree between renders
7195 childrenToRender = childrenToRender.map(function (child) {
7196 var key = child.key;
7197 return exiting.has(key) ? (child) : (React.createElement(PresenceChild, { key: getChildKey(child) }, child));
7198 });
7199 presentChildren.current = childrenToRender;
7200 if (
7201 exitBeforeEnter &&
7202 childrenToRender.length > 1) {
7203 console.warn("You're attempting to animate multiple children within AnimatePresence, but its exitBeforeEnter prop is set to true. This will lead to odd visual behaviour.");
7204 }
7205 return (React.createElement(React.Fragment, null, exiting.size
7206 ? childrenToRender
7207 : childrenToRender.map(function (child) { return React.cloneElement(child); })));
7208 };
7209
7210 /**
7211 * When a component is the child of an `AnimatePresence` component, it has access to
7212 * information about whether it's still present the React tree. `usePresence` can be
7213 * used to access that data and perform operations before the component can be considered
7214 * safe to remove.
7215 *
7216 * It returns two values. `isPresent` is a boolean that is `true` when the component
7217 * is present within the React tree. It is `false` when it's been removed, but still visible.
7218 *
7219 * When `isPresent` is `false`, the `safeToRemove` callback can be used to tell `AnimatePresence`
7220 * that it's safe to remove the component from the DOM, for instance after a animation has completed.
7221 *
7222 * ```jsx
7223 * const [isPresent, safeToRemove] = usePresence()
7224 *
7225 * useEffect(() => {
7226 * !isPresent setTimeout(safeToRemove, 1000)
7227 * }, [isPresent])
7228 * ```
7229 *
7230 * @public
7231 */
7232 function usePresence() {
7233 var exitProps = React.useContext(MotionContext).exitProps;
7234 if (!exitProps)
7235 return [true];
7236 var isExiting = exitProps.isExiting, onExitComplete = exitProps.onExitComplete;
7237 return isExiting && onExitComplete ? [false, onExitComplete] : [true];
7238 }
7239
7240 // Does this device prefer reduced motion? Returns `null` server-side.
7241 var prefersReducedMotion = motionValue(null);
7242 if (typeof window !== "undefined") {
7243 if (window.matchMedia) {
7244 var motionMediaQuery_1 = window.matchMedia("(prefers-reduced-motion)");
7245 var setReducedMotionPreferences = function () {
7246 return prefersReducedMotion.set(motionMediaQuery_1.matches);
7247 };
7248 motionMediaQuery_1.addListener(setReducedMotionPreferences);
7249 setReducedMotionPreferences();
7250 }
7251 else {
7252 prefersReducedMotion.set(false);
7253 }
7254 }
7255 function determineShouldReduceMotion(prefersReduced, isReducedMotion) {
7256 return typeof isReducedMotion === "boolean"
7257 ? isReducedMotion
7258 : Boolean(prefersReduced);
7259 }
7260
7261 /**
7262 * A hook that returns `true` if we should be using reduced motion based on the current device's Reduced Motion setting.
7263 *
7264 * This can be used to implement changes to your UI based on Reduced Motion. For instance, replacing motion-sickness inducing
7265 * `x`/`y` animations with `opacity`, disabling the autoplay of background videos, or turning off parallax motion.
7266 *
7267 * It will actively respond to changes and re-render your components with the latest setting.
7268 *
7269 * ```jsx
7270 * export function Sidebar({ isOpem }) {
7271 * const shouldReduceMotion = useReducedMotion()
7272 * const closedX = shouldReduceMotion ? 0 : "-100%"
7273 *
7274 * return (
7275 * <motion.div animate={{
7276 * opacity: isOpen ? 1 : 0,
7277 * x: isOpen ? 0 : closedX
7278 * }} />
7279 * )
7280 * }
7281 * ```
7282 *
7283 * @return boolean
7284 *
7285 * @public
7286 */
7287 function useReducedMotion() {
7288 var isReducedMotion = React.useContext(MotionContext).isReducedMotion;
7289 var _a = React.useState(determineShouldReduceMotion(prefersReducedMotion.get(), isReducedMotion)), shouldReduceMotion = _a[0], setShouldReduceMotion = _a[1];
7290 React.useEffect(function () {
7291 return prefersReducedMotion.onChange(function (v) {
7292 setShouldReduceMotion(determineShouldReduceMotion(v, isReducedMotion));
7293 });
7294 }, [setShouldReduceMotion, isReducedMotion]);
7295 return shouldReduceMotion;
7296 }
7297
7298 /**
7299 * Define accessibility options for a tree. Can be used to force the tree into Reduced Motion mode,
7300 * or disable device detection.
7301 *
7302 * @internal
7303 */
7304 function ReducedMotion(_a) {
7305 var children = _a.children, enabled = _a.enabled;
7306 var context = React.useContext(MotionContext);
7307 context = React.useMemo(function () { return (__assign(__assign({}, context), { isReducedMotion: enabled })); }, [enabled]);
7308 return (React.createElement(MotionContext.Provider, { value: context }, children));
7309 }
7310
7311 exports.AnimatePresence = AnimatePresence;
7312 exports.AnimationControls = AnimationControls;
7313 exports.DragControls = DragControls;
7314 exports.MotionContext = MotionContext;
7315 exports.MotionPluginContext = MotionPluginContext;
7316 exports.MotionPlugins = MotionPlugins;
7317 exports.MotionValue = MotionValue;
7318 exports.ReducedMotion = ReducedMotion;
7319 exports.UnstableSyncLayout = UnstableSyncLayout;
7320 exports.animationControls = animationControls;
7321 exports.createMotionComponent = createMotionComponent;
7322 exports.isValidMotionProp = isValidMotionProp;
7323 exports.motion = motion;
7324 exports.motionValue = motionValue;
7325 exports.transform = transform;
7326 exports.unwrapMotionValue = unwrapMotionValue;
7327 exports.useAnimatedState = useAnimatedState;
7328 exports.useAnimation = useAnimation;
7329 exports.useCycle = useCycle;
7330 exports.useDomEvent = useDomEvent;
7331 exports.useDragControls = useDragControls;
7332 exports.useExternalRef = useExternalRef;
7333 exports.useGestures = useGestures;
7334 exports.useInvertedScale = useInvertedScale;
7335 exports.useMotionValue = useMotionValue;
7336 exports.usePanGesture = usePanGesture;
7337 exports.usePresence = usePresence;
7338 exports.useReducedMotion = useReducedMotion;
7339 exports.useSpring = useSpring;
7340 exports.useTapGesture = useTapGesture;
7341 exports.useTransform = useTransform;
7342 exports.useViewportScroll = useViewportScroll;
7343
7344 Object.defineProperty(exports, '__esModule', { value: true });
7345
7346}));