motion 11.16.4 → 11.16.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/dist/cjs/index.js +660 -659
  2. package/dist/cjs/react-client.js +524 -523
  3. package/dist/cjs/react-m.js +6 -6
  4. package/dist/es/framer-motion/dist/es/animation/animate/index.mjs +1 -1
  5. package/dist/es/framer-motion/dist/es/animation/interfaces/visual-element-target.mjs +2 -2
  6. package/dist/es/framer-motion/dist/es/animation/optimized-appear/store-id.mjs +1 -1
  7. package/dist/es/framer-motion/dist/es/animation/utils/default-transitions.mjs +1 -1
  8. package/dist/es/framer-motion/dist/es/motion/utils/is-forced-motion-value.mjs +1 -1
  9. package/dist/es/framer-motion/dist/es/render/VisualElement.mjs +12 -12
  10. package/dist/es/framer-motion/dist/es/render/dom/DOMKeyframesResolver.mjs +4 -3
  11. package/dist/es/framer-motion/dist/es/render/dom/scroll/offsets/index.mjs +6 -5
  12. package/dist/es/framer-motion/dist/es/render/dom/utils/unit-conversion.mjs +2 -14
  13. package/dist/es/framer-motion/dist/es/render/html/HTMLVisualElement.mjs +6 -6
  14. package/dist/es/framer-motion/dist/es/render/html/utils/build-styles.mjs +2 -2
  15. package/dist/es/framer-motion/dist/es/render/html/utils/build-transform.mjs +1 -1
  16. package/dist/es/framer-motion/dist/es/render/html/utils/keys-position.mjs +13 -0
  17. package/dist/es/framer-motion/dist/es/render/svg/SVGVisualElement.mjs +6 -6
  18. package/dist/es/framer-motion/dist/es/render/svg/utils/scrape-motion-values.mjs +1 -1
  19. package/dist/es/framer-motion/dist/es/render/utils/motion-values.mjs +1 -1
  20. package/dist/es/framer-motion/dist/es/utils/interpolate.mjs +4 -1
  21. package/dist/es/framer-motion/dist/es/value/index.mjs +1 -1
  22. package/dist/es/framer-motion/dist/es/value/use-will-change/get-will-change-name.mjs +1 -1
  23. package/dist/motion.dev.js +660 -659
  24. package/dist/motion.js +1 -1
  25. package/package.json +3 -3
  26. /package/dist/es/framer-motion/dist/es/render/html/utils/{transform.mjs → keys-transform.mjs} +0 -0
@@ -621,6 +621,16 @@ const transformPropOrder = [
621
621
  */
622
622
  const transformProps = new Set(transformPropOrder);
623
623
 
624
+ const positionalKeys = new Set([
625
+ "width",
626
+ "height",
627
+ "top",
628
+ "left",
629
+ "right",
630
+ "bottom",
631
+ ...transformPropOrder,
632
+ ]);
633
+
624
634
  const isCustomValue = (v) => {
625
635
  return Boolean(v && typeof v === "object" && v.mix && v.toValue);
626
636
  };
@@ -905,7 +915,7 @@ class MotionValue {
905
915
  * This will be replaced by the build step with the latest version number.
906
916
  * When MotionValues are provided to motion components, warn if versions are mixed.
907
917
  */
908
- this.version = "11.16.4";
918
+ this.version = "11.16.7";
909
919
  /**
910
920
  * Tracks whether this value can output a velocity. Currently this is only true
911
921
  * if the value is numerical, but we might be able to widen the scope here and support
@@ -1318,62 +1328,6 @@ function isNone(value) {
1318
1328
  }
1319
1329
  }
1320
1330
 
1321
- /**
1322
- * Check if value is a numerical string, ie a string that is purely a number eg "100" or "-100.1"
1323
- */
1324
- const isNumericalString = (v) => /^-?(?:\d+(?:\.\d+)?|\.\d+)$/u.test(v);
1325
-
1326
- const checkStringStartsWith = (token) => (key) => typeof key === "string" && key.startsWith(token);
1327
- const isCSSVariableName =
1328
- /*@__PURE__*/ checkStringStartsWith("--");
1329
- const startsAsVariableToken =
1330
- /*@__PURE__*/ checkStringStartsWith("var(--");
1331
- const isCSSVariableToken = (value) => {
1332
- const startsWithToken = startsAsVariableToken(value);
1333
- if (!startsWithToken)
1334
- return false;
1335
- // Ensure any comments are stripped from the value as this can harm performance of the regex.
1336
- return singleCssVariableRegex.test(value.split("/*")[0].trim());
1337
- };
1338
- const singleCssVariableRegex = /var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu;
1339
-
1340
- /**
1341
- * Parse Framer's special CSS variable format into a CSS token and a fallback.
1342
- *
1343
- * ```
1344
- * `var(--foo, #fff)` => [`--foo`, '#fff']
1345
- * ```
1346
- *
1347
- * @param current
1348
- */
1349
- const splitCSSVariableRegex =
1350
- // eslint-disable-next-line redos-detector/no-unsafe-regex -- false positive, as it can match a lot of words
1351
- /^var\(--(?:([\w-]+)|([\w-]+), ?([a-zA-Z\d ()%#.,-]+))\)/u;
1352
- function parseCSSVariable(current) {
1353
- const match = splitCSSVariableRegex.exec(current);
1354
- if (!match)
1355
- return [,];
1356
- const [, token1, token2, fallback] = match;
1357
- return [`--${token1 !== null && token1 !== void 0 ? token1 : token2}`, fallback];
1358
- }
1359
- const maxDepth = 4;
1360
- function getVariableValue(current, element, depth = 1) {
1361
- invariant(depth <= maxDepth, `Max CSS variable fallback depth detected in property "${current}". This may indicate a circular fallback dependency.`);
1362
- const [token, fallback] = parseCSSVariable(current);
1363
- // No CSS variable detected
1364
- if (!token)
1365
- return;
1366
- // Attempt to read this CSS variable off the element
1367
- const resolved = window.getComputedStyle(element).getPropertyValue(token);
1368
- if (resolved) {
1369
- const trimmed = resolved.trim();
1370
- return isNumericalString(trimmed) ? parseFloat(trimmed) : trimmed;
1371
- }
1372
- return isCSSVariableToken(fallback)
1373
- ? getVariableValue(fallback, element, depth + 1)
1374
- : fallback;
1375
- }
1376
-
1377
1331
  const clamp = (min, max, v) => {
1378
1332
  if (v > max)
1379
1333
  return max;
@@ -1396,6 +1350,97 @@ const scale = {
1396
1350
  default: 1,
1397
1351
  };
1398
1352
 
1353
+ // If this number is a decimal, make it just five decimal places
1354
+ // to avoid exponents
1355
+ const sanitize = (v) => Math.round(v * 100000) / 100000;
1356
+
1357
+ const floatRegex = /-?(?:\d+(?:\.\d+)?|\.\d+)/gu;
1358
+
1359
+ function isNullish(v) {
1360
+ return v == null;
1361
+ }
1362
+
1363
+ const singleColorRegex = /^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))$/iu;
1364
+
1365
+ /**
1366
+ * Returns true if the provided string is a color, ie rgba(0,0,0,0) or #000,
1367
+ * but false if a number or multiple colors
1368
+ */
1369
+ const isColorString = (type, testProp) => (v) => {
1370
+ return Boolean((typeof v === "string" &&
1371
+ singleColorRegex.test(v) &&
1372
+ v.startsWith(type)) ||
1373
+ (testProp &&
1374
+ !isNullish(v) &&
1375
+ Object.prototype.hasOwnProperty.call(v, testProp)));
1376
+ };
1377
+ const splitColor = (aName, bName, cName) => (v) => {
1378
+ if (typeof v !== "string")
1379
+ return v;
1380
+ const [a, b, c, alpha] = v.match(floatRegex);
1381
+ return {
1382
+ [aName]: parseFloat(a),
1383
+ [bName]: parseFloat(b),
1384
+ [cName]: parseFloat(c),
1385
+ alpha: alpha !== undefined ? parseFloat(alpha) : 1,
1386
+ };
1387
+ };
1388
+
1389
+ const clampRgbUnit = (v) => clamp(0, 255, v);
1390
+ const rgbUnit = {
1391
+ ...number,
1392
+ transform: (v) => Math.round(clampRgbUnit(v)),
1393
+ };
1394
+ const rgba = {
1395
+ test: /*@__PURE__*/ isColorString("rgb", "red"),
1396
+ parse: /*@__PURE__*/ splitColor("red", "green", "blue"),
1397
+ transform: ({ red, green, blue, alpha: alpha$1 = 1 }) => "rgba(" +
1398
+ rgbUnit.transform(red) +
1399
+ ", " +
1400
+ rgbUnit.transform(green) +
1401
+ ", " +
1402
+ rgbUnit.transform(blue) +
1403
+ ", " +
1404
+ sanitize(alpha.transform(alpha$1)) +
1405
+ ")",
1406
+ };
1407
+
1408
+ function parseHex(v) {
1409
+ let r = "";
1410
+ let g = "";
1411
+ let b = "";
1412
+ let a = "";
1413
+ // If we have 6 characters, ie #FF0000
1414
+ if (v.length > 5) {
1415
+ r = v.substring(1, 3);
1416
+ g = v.substring(3, 5);
1417
+ b = v.substring(5, 7);
1418
+ a = v.substring(7, 9);
1419
+ // Or we have 3 characters, ie #F00
1420
+ }
1421
+ else {
1422
+ r = v.substring(1, 2);
1423
+ g = v.substring(2, 3);
1424
+ b = v.substring(3, 4);
1425
+ a = v.substring(4, 5);
1426
+ r += r;
1427
+ g += g;
1428
+ b += b;
1429
+ a += a;
1430
+ }
1431
+ return {
1432
+ red: parseInt(r, 16),
1433
+ green: parseInt(g, 16),
1434
+ blue: parseInt(b, 16),
1435
+ alpha: a ? parseInt(a, 16) / 255 : 1,
1436
+ };
1437
+ }
1438
+ const hex = {
1439
+ test: /*@__PURE__*/ isColorString("#"),
1440
+ parse: parseHex,
1441
+ transform: rgba.transform,
1442
+ };
1443
+
1399
1444
  const createUnitType = (unit) => ({
1400
1445
  test: (v) => typeof v === "string" && v.endsWith(unit) && v.split(" ").length === 1,
1401
1446
  parse: parseFloat,
@@ -1412,87 +1457,347 @@ const progressPercentage = {
1412
1457
  transform: (v) => percent.transform(v * 100),
1413
1458
  };
1414
1459
 
1415
- const positionalKeys = new Set([
1416
- "width",
1417
- "height",
1418
- "top",
1419
- "left",
1420
- "right",
1421
- "bottom",
1422
- "x",
1423
- "y",
1424
- "translateX",
1425
- "translateY",
1426
- ]);
1427
- const isNumOrPxType = (v) => v === number || v === px;
1428
- const getPosFromMatrix = (matrix, pos) => parseFloat(matrix.split(", ")[pos]);
1429
- const getTranslateFromMatrix = (pos2, pos3) => (_bbox, { transform }) => {
1430
- if (transform === "none" || !transform)
1431
- return 0;
1432
- const matrix3d = transform.match(/^matrix3d\((.+)\)$/u);
1433
- if (matrix3d) {
1434
- return getPosFromMatrix(matrix3d[1], pos3);
1435
- }
1436
- else {
1437
- const matrix = transform.match(/^matrix\((.+)\)$/u);
1438
- if (matrix) {
1439
- return getPosFromMatrix(matrix[1], pos2);
1460
+ const hsla = {
1461
+ test: /*@__PURE__*/ isColorString("hsl", "hue"),
1462
+ parse: /*@__PURE__*/ splitColor("hue", "saturation", "lightness"),
1463
+ transform: ({ hue, saturation, lightness, alpha: alpha$1 = 1 }) => {
1464
+ return ("hsla(" +
1465
+ Math.round(hue) +
1466
+ ", " +
1467
+ percent.transform(sanitize(saturation)) +
1468
+ ", " +
1469
+ percent.transform(sanitize(lightness)) +
1470
+ ", " +
1471
+ sanitize(alpha.transform(alpha$1)) +
1472
+ ")");
1473
+ },
1474
+ };
1475
+
1476
+ const color = {
1477
+ test: (v) => rgba.test(v) || hex.test(v) || hsla.test(v),
1478
+ parse: (v) => {
1479
+ if (rgba.test(v)) {
1480
+ return rgba.parse(v);
1440
1481
  }
1441
- else {
1442
- return 0;
1482
+ else if (hsla.test(v)) {
1483
+ return hsla.parse(v);
1443
1484
  }
1444
- }
1445
- };
1446
- const transformKeys = new Set(["x", "y", "z"]);
1447
- const nonTranslationalTransformKeys = transformPropOrder.filter((key) => !transformKeys.has(key));
1448
- function removeNonTranslationalTransform(visualElement) {
1449
- const removedTransforms = [];
1450
- nonTranslationalTransformKeys.forEach((key) => {
1451
- const value = visualElement.getValue(key);
1452
- if (value !== undefined) {
1453
- removedTransforms.push([key, value.get()]);
1454
- value.set(key.startsWith("scale") ? 1 : 0);
1485
+ else {
1486
+ return hex.parse(v);
1455
1487
  }
1456
- });
1457
- return removedTransforms;
1458
- }
1459
- const positionalValues = {
1460
- // Dimensions
1461
- width: ({ x }, { paddingLeft = "0", paddingRight = "0" }) => x.max - x.min - parseFloat(paddingLeft) - parseFloat(paddingRight),
1462
- height: ({ y }, { paddingTop = "0", paddingBottom = "0" }) => y.max - y.min - parseFloat(paddingTop) - parseFloat(paddingBottom),
1463
- top: (_bbox, { top }) => parseFloat(top),
1464
- left: (_bbox, { left }) => parseFloat(left),
1465
- bottom: ({ y }, { top }) => parseFloat(top) + (y.max - y.min),
1466
- right: ({ x }, { left }) => parseFloat(left) + (x.max - x.min),
1467
- // Transform
1468
- x: getTranslateFromMatrix(4, 13),
1469
- y: getTranslateFromMatrix(5, 14),
1488
+ },
1489
+ transform: (v) => {
1490
+ return typeof v === "string"
1491
+ ? v
1492
+ : v.hasOwnProperty("red")
1493
+ ? rgba.transform(v)
1494
+ : hsla.transform(v);
1495
+ },
1470
1496
  };
1471
- // Alias translate longform names
1472
- positionalValues.translateX = positionalValues.x;
1473
- positionalValues.translateY = positionalValues.y;
1474
1497
 
1475
- /**
1476
- * Tests a provided value against a ValueType
1477
- */
1478
- const testValueType = (v) => (type) => type.test(v);
1498
+ const colorRegex = /(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))/giu;
1479
1499
 
1480
- /**
1481
- * ValueType for "auto"
1482
- */
1483
- const auto = {
1484
- test: (v) => v === "auto",
1485
- parse: (v) => v,
1486
- };
1500
+ function test(v) {
1501
+ var _a, _b;
1502
+ return (isNaN(v) &&
1503
+ typeof v === "string" &&
1504
+ (((_a = v.match(floatRegex)) === null || _a === void 0 ? void 0 : _a.length) || 0) +
1505
+ (((_b = v.match(colorRegex)) === null || _b === void 0 ? void 0 : _b.length) || 0) >
1506
+ 0);
1507
+ }
1508
+ const NUMBER_TOKEN = "number";
1509
+ const COLOR_TOKEN = "color";
1510
+ const VAR_TOKEN = "var";
1511
+ const VAR_FUNCTION_TOKEN = "var(";
1512
+ const SPLIT_TOKEN = "${}";
1513
+ // this regex consists of the `singleCssVariableRegex|rgbHSLValueRegex|digitRegex`
1514
+ const complexRegex = /var\s*\(\s*--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)|#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\)|-?(?:\d+(?:\.\d+)?|\.\d+)/giu;
1515
+ function analyseComplexValue(value) {
1516
+ const originalValue = value.toString();
1517
+ const values = [];
1518
+ const indexes = {
1519
+ color: [],
1520
+ number: [],
1521
+ var: [],
1522
+ };
1523
+ const types = [];
1524
+ let i = 0;
1525
+ const tokenised = originalValue.replace(complexRegex, (parsedValue) => {
1526
+ if (color.test(parsedValue)) {
1527
+ indexes.color.push(i);
1528
+ types.push(COLOR_TOKEN);
1529
+ values.push(color.parse(parsedValue));
1530
+ }
1531
+ else if (parsedValue.startsWith(VAR_FUNCTION_TOKEN)) {
1532
+ indexes.var.push(i);
1533
+ types.push(VAR_TOKEN);
1534
+ values.push(parsedValue);
1535
+ }
1536
+ else {
1537
+ indexes.number.push(i);
1538
+ types.push(NUMBER_TOKEN);
1539
+ values.push(parseFloat(parsedValue));
1540
+ }
1541
+ ++i;
1542
+ return SPLIT_TOKEN;
1543
+ });
1544
+ const split = tokenised.split(SPLIT_TOKEN);
1545
+ return { values, split, indexes, types };
1546
+ }
1547
+ function parseComplexValue(v) {
1548
+ return analyseComplexValue(v).values;
1549
+ }
1550
+ function createTransformer(source) {
1551
+ const { split, types } = analyseComplexValue(source);
1552
+ const numSections = split.length;
1553
+ return (v) => {
1554
+ let output = "";
1555
+ for (let i = 0; i < numSections; i++) {
1556
+ output += split[i];
1557
+ if (v[i] !== undefined) {
1558
+ const type = types[i];
1559
+ if (type === NUMBER_TOKEN) {
1560
+ output += sanitize(v[i]);
1561
+ }
1562
+ else if (type === COLOR_TOKEN) {
1563
+ output += color.transform(v[i]);
1564
+ }
1565
+ else {
1566
+ output += v[i];
1567
+ }
1568
+ }
1569
+ }
1570
+ return output;
1571
+ };
1572
+ }
1573
+ const convertNumbersToZero = (v) => typeof v === "number" ? 0 : v;
1574
+ function getAnimatableNone$1(v) {
1575
+ const parsed = parseComplexValue(v);
1576
+ const transformer = createTransformer(v);
1577
+ return transformer(parsed.map(convertNumbersToZero));
1578
+ }
1579
+ const complex = {
1580
+ test,
1581
+ parse: parseComplexValue,
1582
+ createTransformer,
1583
+ getAnimatableNone: getAnimatableNone$1,
1584
+ };
1487
1585
 
1488
1586
  /**
1489
- * A list of value types commonly used for dimensions
1587
+ * Properties that should default to 1 or 100%
1490
1588
  */
1491
- const dimensionValueTypes = [number, px, percent, degrees, vw, vh, auto];
1589
+ const maxDefaults = new Set(["brightness", "contrast", "saturate", "opacity"]);
1590
+ function applyDefaultFilter(v) {
1591
+ const [name, value] = v.slice(0, -1).split("(");
1592
+ if (name === "drop-shadow")
1593
+ return v;
1594
+ const [number] = value.match(floatRegex) || [];
1595
+ if (!number)
1596
+ return v;
1597
+ const unit = value.replace(number, "");
1598
+ let defaultValue = maxDefaults.has(name) ? 1 : 0;
1599
+ if (number !== value)
1600
+ defaultValue *= 100;
1601
+ return name + "(" + defaultValue + unit + ")";
1602
+ }
1603
+ const functionRegex = /\b([a-z-]*)\(.*?\)/gu;
1604
+ const filter = {
1605
+ ...complex,
1606
+ getAnimatableNone: (v) => {
1607
+ const functions = v.match(functionRegex);
1608
+ return functions ? functions.map(applyDefaultFilter).join(" ") : v;
1609
+ },
1610
+ };
1611
+
1612
+ const browserNumberValueTypes = {
1613
+ // Border props
1614
+ borderWidth: px,
1615
+ borderTopWidth: px,
1616
+ borderRightWidth: px,
1617
+ borderBottomWidth: px,
1618
+ borderLeftWidth: px,
1619
+ borderRadius: px,
1620
+ radius: px,
1621
+ borderTopLeftRadius: px,
1622
+ borderTopRightRadius: px,
1623
+ borderBottomRightRadius: px,
1624
+ borderBottomLeftRadius: px,
1625
+ // Positioning props
1626
+ width: px,
1627
+ maxWidth: px,
1628
+ height: px,
1629
+ maxHeight: px,
1630
+ top: px,
1631
+ right: px,
1632
+ bottom: px,
1633
+ left: px,
1634
+ // Spacing props
1635
+ padding: px,
1636
+ paddingTop: px,
1637
+ paddingRight: px,
1638
+ paddingBottom: px,
1639
+ paddingLeft: px,
1640
+ margin: px,
1641
+ marginTop: px,
1642
+ marginRight: px,
1643
+ marginBottom: px,
1644
+ marginLeft: px,
1645
+ // Misc
1646
+ backgroundPositionX: px,
1647
+ backgroundPositionY: px,
1648
+ };
1649
+
1650
+ const transformValueTypes = {
1651
+ rotate: degrees,
1652
+ rotateX: degrees,
1653
+ rotateY: degrees,
1654
+ rotateZ: degrees,
1655
+ scale,
1656
+ scaleX: scale,
1657
+ scaleY: scale,
1658
+ scaleZ: scale,
1659
+ skew: degrees,
1660
+ skewX: degrees,
1661
+ skewY: degrees,
1662
+ distance: px,
1663
+ translateX: px,
1664
+ translateY: px,
1665
+ translateZ: px,
1666
+ x: px,
1667
+ y: px,
1668
+ z: px,
1669
+ perspective: px,
1670
+ transformPerspective: px,
1671
+ opacity: alpha,
1672
+ originX: progressPercentage,
1673
+ originY: progressPercentage,
1674
+ originZ: px,
1675
+ };
1676
+
1677
+ const int = {
1678
+ ...number,
1679
+ transform: Math.round,
1680
+ };
1681
+
1682
+ const numberValueTypes = {
1683
+ ...browserNumberValueTypes,
1684
+ ...transformValueTypes,
1685
+ zIndex: int,
1686
+ size: px,
1687
+ // SVG
1688
+ fillOpacity: alpha,
1689
+ strokeOpacity: alpha,
1690
+ numOctaves: int,
1691
+ };
1692
+
1492
1693
  /**
1493
- * Tests a dimensional value against the list of dimension ValueTypes
1694
+ * A map of default value types for common values
1494
1695
  */
1495
- const findDimensionValueType = (v) => dimensionValueTypes.find(testValueType(v));
1696
+ const defaultValueTypes = {
1697
+ ...numberValueTypes,
1698
+ // Color props
1699
+ color,
1700
+ backgroundColor: color,
1701
+ outlineColor: color,
1702
+ fill: color,
1703
+ stroke: color,
1704
+ // Border props
1705
+ borderColor: color,
1706
+ borderTopColor: color,
1707
+ borderRightColor: color,
1708
+ borderBottomColor: color,
1709
+ borderLeftColor: color,
1710
+ filter,
1711
+ WebkitFilter: filter,
1712
+ };
1713
+ /**
1714
+ * Gets the default ValueType for the provided value key
1715
+ */
1716
+ const getDefaultValueType = (key) => defaultValueTypes[key];
1717
+
1718
+ function getAnimatableNone(key, value) {
1719
+ let defaultValueType = getDefaultValueType(key);
1720
+ if (defaultValueType !== filter)
1721
+ defaultValueType = complex;
1722
+ // If value is not recognised as animatable, ie "none", create an animatable version origin based on the target
1723
+ return defaultValueType.getAnimatableNone
1724
+ ? defaultValueType.getAnimatableNone(value)
1725
+ : undefined;
1726
+ }
1727
+
1728
+ /**
1729
+ * If we encounter keyframes like "none" or "0" and we also have keyframes like
1730
+ * "#fff" or "200px 200px" we want to find a keyframe to serve as a template for
1731
+ * the "none" keyframes. In this case "#fff" or "200px 200px" - then these get turned into
1732
+ * zero equivalents, i.e. "#fff0" or "0px 0px".
1733
+ */
1734
+ const invalidTemplates = new Set(["auto", "none", "0"]);
1735
+ function makeNoneKeyframesAnimatable(unresolvedKeyframes, noneKeyframeIndexes, name) {
1736
+ let i = 0;
1737
+ let animatableTemplate = undefined;
1738
+ while (i < unresolvedKeyframes.length && !animatableTemplate) {
1739
+ const keyframe = unresolvedKeyframes[i];
1740
+ if (typeof keyframe === "string" &&
1741
+ !invalidTemplates.has(keyframe) &&
1742
+ analyseComplexValue(keyframe).values.length) {
1743
+ animatableTemplate = unresolvedKeyframes[i];
1744
+ }
1745
+ i++;
1746
+ }
1747
+ if (animatableTemplate && name) {
1748
+ for (const noneIndex of noneKeyframeIndexes) {
1749
+ unresolvedKeyframes[noneIndex] = getAnimatableNone(name, animatableTemplate);
1750
+ }
1751
+ }
1752
+ }
1753
+
1754
+ const isNumOrPxType = (v) => v === number || v === px;
1755
+ const getPosFromMatrix = (matrix, pos) => parseFloat(matrix.split(", ")[pos]);
1756
+ const getTranslateFromMatrix = (pos2, pos3) => (_bbox, { transform }) => {
1757
+ if (transform === "none" || !transform)
1758
+ return 0;
1759
+ const matrix3d = transform.match(/^matrix3d\((.+)\)$/u);
1760
+ if (matrix3d) {
1761
+ return getPosFromMatrix(matrix3d[1], pos3);
1762
+ }
1763
+ else {
1764
+ const matrix = transform.match(/^matrix\((.+)\)$/u);
1765
+ if (matrix) {
1766
+ return getPosFromMatrix(matrix[1], pos2);
1767
+ }
1768
+ else {
1769
+ return 0;
1770
+ }
1771
+ }
1772
+ };
1773
+ const transformKeys = new Set(["x", "y", "z"]);
1774
+ const nonTranslationalTransformKeys = transformPropOrder.filter((key) => !transformKeys.has(key));
1775
+ function removeNonTranslationalTransform(visualElement) {
1776
+ const removedTransforms = [];
1777
+ nonTranslationalTransformKeys.forEach((key) => {
1778
+ const value = visualElement.getValue(key);
1779
+ if (value !== undefined) {
1780
+ removedTransforms.push([key, value.get()]);
1781
+ value.set(key.startsWith("scale") ? 1 : 0);
1782
+ }
1783
+ });
1784
+ return removedTransforms;
1785
+ }
1786
+ const positionalValues = {
1787
+ // Dimensions
1788
+ width: ({ x }, { paddingLeft = "0", paddingRight = "0" }) => x.max - x.min - parseFloat(paddingLeft) - parseFloat(paddingRight),
1789
+ height: ({ y }, { paddingTop = "0", paddingBottom = "0" }) => y.max - y.min - parseFloat(paddingTop) - parseFloat(paddingBottom),
1790
+ top: (_bbox, { top }) => parseFloat(top),
1791
+ left: (_bbox, { left }) => parseFloat(left),
1792
+ bottom: ({ y }, { top }) => parseFloat(top) + (y.max - y.min),
1793
+ right: ({ x }, { left }) => parseFloat(left) + (x.max - x.min),
1794
+ // Transform
1795
+ x: getTranslateFromMatrix(4, 13),
1796
+ y: getTranslateFromMatrix(5, 14),
1797
+ };
1798
+ // Alias translate longform names
1799
+ positionalValues.translateX = positionalValues.x;
1800
+ positionalValues.translateY = positionalValues.y;
1496
1801
 
1497
1802
  const toResolve = new Set();
1498
1803
  let isScheduled = false;
@@ -1640,404 +1945,97 @@ class KeyframeResolver {
1640
1945
  complete() {
1641
1946
  this.isComplete = true;
1642
1947
  this.onComplete(this.unresolvedKeyframes, this.finalKeyframe);
1643
- toResolve.delete(this);
1644
- }
1645
- cancel() {
1646
- if (!this.isComplete) {
1647
- this.isScheduled = false;
1648
- toResolve.delete(this);
1649
- }
1650
- }
1651
- resume() {
1652
- if (!this.isComplete)
1653
- this.scheduleResolve();
1654
- }
1655
- }
1656
-
1657
- // If this number is a decimal, make it just five decimal places
1658
- // to avoid exponents
1659
- const sanitize = (v) => Math.round(v * 100000) / 100000;
1660
-
1661
- const floatRegex = /-?(?:\d+(?:\.\d+)?|\.\d+)/gu;
1662
-
1663
- function isNullish(v) {
1664
- return v == null;
1665
- }
1666
-
1667
- const singleColorRegex = /^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))$/iu;
1668
-
1669
- /**
1670
- * Returns true if the provided string is a color, ie rgba(0,0,0,0) or #000,
1671
- * but false if a number or multiple colors
1672
- */
1673
- const isColorString = (type, testProp) => (v) => {
1674
- return Boolean((typeof v === "string" &&
1675
- singleColorRegex.test(v) &&
1676
- v.startsWith(type)) ||
1677
- (testProp &&
1678
- !isNullish(v) &&
1679
- Object.prototype.hasOwnProperty.call(v, testProp)));
1680
- };
1681
- const splitColor = (aName, bName, cName) => (v) => {
1682
- if (typeof v !== "string")
1683
- return v;
1684
- const [a, b, c, alpha] = v.match(floatRegex);
1685
- return {
1686
- [aName]: parseFloat(a),
1687
- [bName]: parseFloat(b),
1688
- [cName]: parseFloat(c),
1689
- alpha: alpha !== undefined ? parseFloat(alpha) : 1,
1690
- };
1691
- };
1692
-
1693
- const clampRgbUnit = (v) => clamp(0, 255, v);
1694
- const rgbUnit = {
1695
- ...number,
1696
- transform: (v) => Math.round(clampRgbUnit(v)),
1697
- };
1698
- const rgba = {
1699
- test: /*@__PURE__*/ isColorString("rgb", "red"),
1700
- parse: /*@__PURE__*/ splitColor("red", "green", "blue"),
1701
- transform: ({ red, green, blue, alpha: alpha$1 = 1 }) => "rgba(" +
1702
- rgbUnit.transform(red) +
1703
- ", " +
1704
- rgbUnit.transform(green) +
1705
- ", " +
1706
- rgbUnit.transform(blue) +
1707
- ", " +
1708
- sanitize(alpha.transform(alpha$1)) +
1709
- ")",
1710
- };
1711
-
1712
- function parseHex(v) {
1713
- let r = "";
1714
- let g = "";
1715
- let b = "";
1716
- let a = "";
1717
- // If we have 6 characters, ie #FF0000
1718
- if (v.length > 5) {
1719
- r = v.substring(1, 3);
1720
- g = v.substring(3, 5);
1721
- b = v.substring(5, 7);
1722
- a = v.substring(7, 9);
1723
- // Or we have 3 characters, ie #F00
1724
- }
1725
- else {
1726
- r = v.substring(1, 2);
1727
- g = v.substring(2, 3);
1728
- b = v.substring(3, 4);
1729
- a = v.substring(4, 5);
1730
- r += r;
1731
- g += g;
1732
- b += b;
1733
- a += a;
1734
- }
1735
- return {
1736
- red: parseInt(r, 16),
1737
- green: parseInt(g, 16),
1738
- blue: parseInt(b, 16),
1739
- alpha: a ? parseInt(a, 16) / 255 : 1,
1740
- };
1741
- }
1742
- const hex = {
1743
- test: /*@__PURE__*/ isColorString("#"),
1744
- parse: parseHex,
1745
- transform: rgba.transform,
1746
- };
1747
-
1748
- const hsla = {
1749
- test: /*@__PURE__*/ isColorString("hsl", "hue"),
1750
- parse: /*@__PURE__*/ splitColor("hue", "saturation", "lightness"),
1751
- transform: ({ hue, saturation, lightness, alpha: alpha$1 = 1 }) => {
1752
- return ("hsla(" +
1753
- Math.round(hue) +
1754
- ", " +
1755
- percent.transform(sanitize(saturation)) +
1756
- ", " +
1757
- percent.transform(sanitize(lightness)) +
1758
- ", " +
1759
- sanitize(alpha.transform(alpha$1)) +
1760
- ")");
1761
- },
1762
- };
1763
-
1764
- const color = {
1765
- test: (v) => rgba.test(v) || hex.test(v) || hsla.test(v),
1766
- parse: (v) => {
1767
- if (rgba.test(v)) {
1768
- return rgba.parse(v);
1769
- }
1770
- else if (hsla.test(v)) {
1771
- return hsla.parse(v);
1772
- }
1773
- else {
1774
- return hex.parse(v);
1775
- }
1776
- },
1777
- transform: (v) => {
1778
- return typeof v === "string"
1779
- ? v
1780
- : v.hasOwnProperty("red")
1781
- ? rgba.transform(v)
1782
- : hsla.transform(v);
1783
- },
1784
- };
1785
-
1786
- const colorRegex = /(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))/giu;
1787
-
1788
- function test(v) {
1789
- var _a, _b;
1790
- return (isNaN(v) &&
1791
- typeof v === "string" &&
1792
- (((_a = v.match(floatRegex)) === null || _a === void 0 ? void 0 : _a.length) || 0) +
1793
- (((_b = v.match(colorRegex)) === null || _b === void 0 ? void 0 : _b.length) || 0) >
1794
- 0);
1795
- }
1796
- const NUMBER_TOKEN = "number";
1797
- const COLOR_TOKEN = "color";
1798
- const VAR_TOKEN = "var";
1799
- const VAR_FUNCTION_TOKEN = "var(";
1800
- const SPLIT_TOKEN = "${}";
1801
- // this regex consists of the `singleCssVariableRegex|rgbHSLValueRegex|digitRegex`
1802
- const complexRegex = /var\s*\(\s*--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)|#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\)|-?(?:\d+(?:\.\d+)?|\.\d+)/giu;
1803
- function analyseComplexValue(value) {
1804
- const originalValue = value.toString();
1805
- const values = [];
1806
- const indexes = {
1807
- color: [],
1808
- number: [],
1809
- var: [],
1810
- };
1811
- const types = [];
1812
- let i = 0;
1813
- const tokenised = originalValue.replace(complexRegex, (parsedValue) => {
1814
- if (color.test(parsedValue)) {
1815
- indexes.color.push(i);
1816
- types.push(COLOR_TOKEN);
1817
- values.push(color.parse(parsedValue));
1818
- }
1819
- else if (parsedValue.startsWith(VAR_FUNCTION_TOKEN)) {
1820
- indexes.var.push(i);
1821
- types.push(VAR_TOKEN);
1822
- values.push(parsedValue);
1823
- }
1824
- else {
1825
- indexes.number.push(i);
1826
- types.push(NUMBER_TOKEN);
1827
- values.push(parseFloat(parsedValue));
1828
- }
1829
- ++i;
1830
- return SPLIT_TOKEN;
1831
- });
1832
- const split = tokenised.split(SPLIT_TOKEN);
1833
- return { values, split, indexes, types };
1834
- }
1835
- function parseComplexValue(v) {
1836
- return analyseComplexValue(v).values;
1837
- }
1838
- function createTransformer(source) {
1839
- const { split, types } = analyseComplexValue(source);
1840
- const numSections = split.length;
1841
- return (v) => {
1842
- let output = "";
1843
- for (let i = 0; i < numSections; i++) {
1844
- output += split[i];
1845
- if (v[i] !== undefined) {
1846
- const type = types[i];
1847
- if (type === NUMBER_TOKEN) {
1848
- output += sanitize(v[i]);
1849
- }
1850
- else if (type === COLOR_TOKEN) {
1851
- output += color.transform(v[i]);
1852
- }
1853
- else {
1854
- output += v[i];
1855
- }
1856
- }
1857
- }
1858
- return output;
1859
- };
1860
- }
1861
- const convertNumbersToZero = (v) => typeof v === "number" ? 0 : v;
1862
- function getAnimatableNone$1(v) {
1863
- const parsed = parseComplexValue(v);
1864
- const transformer = createTransformer(v);
1865
- return transformer(parsed.map(convertNumbersToZero));
1948
+ toResolve.delete(this);
1949
+ }
1950
+ cancel() {
1951
+ if (!this.isComplete) {
1952
+ this.isScheduled = false;
1953
+ toResolve.delete(this);
1954
+ }
1955
+ }
1956
+ resume() {
1957
+ if (!this.isComplete)
1958
+ this.scheduleResolve();
1959
+ }
1866
1960
  }
1867
- const complex = {
1868
- test,
1869
- parse: parseComplexValue,
1870
- createTransformer,
1871
- getAnimatableNone: getAnimatableNone$1,
1872
- };
1873
1961
 
1874
1962
  /**
1875
- * Properties that should default to 1 or 100%
1963
+ * Check if value is a numerical string, ie a string that is purely a number eg "100" or "-100.1"
1876
1964
  */
1877
- const maxDefaults = new Set(["brightness", "contrast", "saturate", "opacity"]);
1878
- function applyDefaultFilter(v) {
1879
- const [name, value] = v.slice(0, -1).split("(");
1880
- if (name === "drop-shadow")
1881
- return v;
1882
- const [number] = value.match(floatRegex) || [];
1883
- if (!number)
1884
- return v;
1885
- const unit = value.replace(number, "");
1886
- let defaultValue = maxDefaults.has(name) ? 1 : 0;
1887
- if (number !== value)
1888
- defaultValue *= 100;
1889
- return name + "(" + defaultValue + unit + ")";
1890
- }
1891
- const functionRegex = /\b([a-z-]*)\(.*?\)/gu;
1892
- const filter = {
1893
- ...complex,
1894
- getAnimatableNone: (v) => {
1895
- const functions = v.match(functionRegex);
1896
- return functions ? functions.map(applyDefaultFilter).join(" ") : v;
1897
- },
1898
- };
1899
-
1900
- const browserNumberValueTypes = {
1901
- // Border props
1902
- borderWidth: px,
1903
- borderTopWidth: px,
1904
- borderRightWidth: px,
1905
- borderBottomWidth: px,
1906
- borderLeftWidth: px,
1907
- borderRadius: px,
1908
- radius: px,
1909
- borderTopLeftRadius: px,
1910
- borderTopRightRadius: px,
1911
- borderBottomRightRadius: px,
1912
- borderBottomLeftRadius: px,
1913
- // Positioning props
1914
- width: px,
1915
- maxWidth: px,
1916
- height: px,
1917
- maxHeight: px,
1918
- top: px,
1919
- right: px,
1920
- bottom: px,
1921
- left: px,
1922
- // Spacing props
1923
- padding: px,
1924
- paddingTop: px,
1925
- paddingRight: px,
1926
- paddingBottom: px,
1927
- paddingLeft: px,
1928
- margin: px,
1929
- marginTop: px,
1930
- marginRight: px,
1931
- marginBottom: px,
1932
- marginLeft: px,
1933
- // Misc
1934
- backgroundPositionX: px,
1935
- backgroundPositionY: px,
1936
- };
1965
+ const isNumericalString = (v) => /^-?(?:\d+(?:\.\d+)?|\.\d+)$/u.test(v);
1937
1966
 
1938
- const transformValueTypes = {
1939
- rotate: degrees,
1940
- rotateX: degrees,
1941
- rotateY: degrees,
1942
- rotateZ: degrees,
1943
- scale,
1944
- scaleX: scale,
1945
- scaleY: scale,
1946
- scaleZ: scale,
1947
- skew: degrees,
1948
- skewX: degrees,
1949
- skewY: degrees,
1950
- distance: px,
1951
- translateX: px,
1952
- translateY: px,
1953
- translateZ: px,
1954
- x: px,
1955
- y: px,
1956
- z: px,
1957
- perspective: px,
1958
- transformPerspective: px,
1959
- opacity: alpha,
1960
- originX: progressPercentage,
1961
- originY: progressPercentage,
1962
- originZ: px,
1967
+ const checkStringStartsWith = (token) => (key) => typeof key === "string" && key.startsWith(token);
1968
+ const isCSSVariableName =
1969
+ /*@__PURE__*/ checkStringStartsWith("--");
1970
+ const startsAsVariableToken =
1971
+ /*@__PURE__*/ checkStringStartsWith("var(--");
1972
+ const isCSSVariableToken = (value) => {
1973
+ const startsWithToken = startsAsVariableToken(value);
1974
+ if (!startsWithToken)
1975
+ return false;
1976
+ // Ensure any comments are stripped from the value as this can harm performance of the regex.
1977
+ return singleCssVariableRegex.test(value.split("/*")[0].trim());
1963
1978
  };
1979
+ const singleCssVariableRegex = /var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu;
1964
1980
 
1965
- const int = {
1966
- ...number,
1967
- transform: Math.round,
1968
- };
1981
+ /**
1982
+ * Parse Framer's special CSS variable format into a CSS token and a fallback.
1983
+ *
1984
+ * ```
1985
+ * `var(--foo, #fff)` => [`--foo`, '#fff']
1986
+ * ```
1987
+ *
1988
+ * @param current
1989
+ */
1990
+ const splitCSSVariableRegex =
1991
+ // eslint-disable-next-line redos-detector/no-unsafe-regex -- false positive, as it can match a lot of words
1992
+ /^var\(--(?:([\w-]+)|([\w-]+), ?([a-zA-Z\d ()%#.,-]+))\)/u;
1993
+ function parseCSSVariable(current) {
1994
+ const match = splitCSSVariableRegex.exec(current);
1995
+ if (!match)
1996
+ return [,];
1997
+ const [, token1, token2, fallback] = match;
1998
+ return [`--${token1 !== null && token1 !== void 0 ? token1 : token2}`, fallback];
1999
+ }
2000
+ const maxDepth = 4;
2001
+ function getVariableValue(current, element, depth = 1) {
2002
+ invariant(depth <= maxDepth, `Max CSS variable fallback depth detected in property "${current}". This may indicate a circular fallback dependency.`);
2003
+ const [token, fallback] = parseCSSVariable(current);
2004
+ // No CSS variable detected
2005
+ if (!token)
2006
+ return;
2007
+ // Attempt to read this CSS variable off the element
2008
+ const resolved = window.getComputedStyle(element).getPropertyValue(token);
2009
+ if (resolved) {
2010
+ const trimmed = resolved.trim();
2011
+ return isNumericalString(trimmed) ? parseFloat(trimmed) : trimmed;
2012
+ }
2013
+ return isCSSVariableToken(fallback)
2014
+ ? getVariableValue(fallback, element, depth + 1)
2015
+ : fallback;
2016
+ }
1969
2017
 
1970
- const numberValueTypes = {
1971
- ...browserNumberValueTypes,
1972
- ...transformValueTypes,
1973
- zIndex: int,
1974
- size: px,
1975
- // SVG
1976
- fillOpacity: alpha,
1977
- strokeOpacity: alpha,
1978
- numOctaves: int,
1979
- };
2018
+ /**
2019
+ * Tests a provided value against a ValueType
2020
+ */
2021
+ const testValueType = (v) => (type) => type.test(v);
1980
2022
 
1981
2023
  /**
1982
- * A map of default value types for common values
2024
+ * ValueType for "auto"
1983
2025
  */
1984
- const defaultValueTypes = {
1985
- ...numberValueTypes,
1986
- // Color props
1987
- color,
1988
- backgroundColor: color,
1989
- outlineColor: color,
1990
- fill: color,
1991
- stroke: color,
1992
- // Border props
1993
- borderColor: color,
1994
- borderTopColor: color,
1995
- borderRightColor: color,
1996
- borderBottomColor: color,
1997
- borderLeftColor: color,
1998
- filter,
1999
- WebkitFilter: filter,
2026
+ const auto = {
2027
+ test: (v) => v === "auto",
2028
+ parse: (v) => v,
2000
2029
  };
2030
+
2001
2031
  /**
2002
- * Gets the default ValueType for the provided value key
2032
+ * A list of value types commonly used for dimensions
2003
2033
  */
2004
- const getDefaultValueType = (key) => defaultValueTypes[key];
2005
-
2006
- function getAnimatableNone(key, value) {
2007
- let defaultValueType = getDefaultValueType(key);
2008
- if (defaultValueType !== filter)
2009
- defaultValueType = complex;
2010
- // If value is not recognised as animatable, ie "none", create an animatable version origin based on the target
2011
- return defaultValueType.getAnimatableNone
2012
- ? defaultValueType.getAnimatableNone(value)
2013
- : undefined;
2014
- }
2015
-
2034
+ const dimensionValueTypes = [number, px, percent, degrees, vw, vh, auto];
2016
2035
  /**
2017
- * If we encounter keyframes like "none" or "0" and we also have keyframes like
2018
- * "#fff" or "200px 200px" we want to find a keyframe to serve as a template for
2019
- * the "none" keyframes. In this case "#fff" or "200px 200px" - then these get turned into
2020
- * zero equivalents, i.e. "#fff0" or "0px 0px".
2036
+ * Tests a dimensional value against the list of dimension ValueTypes
2021
2037
  */
2022
- const invalidTemplates = new Set(["auto", "none", "0"]);
2023
- function makeNoneKeyframesAnimatable(unresolvedKeyframes, noneKeyframeIndexes, name) {
2024
- let i = 0;
2025
- let animatableTemplate = undefined;
2026
- while (i < unresolvedKeyframes.length && !animatableTemplate) {
2027
- const keyframe = unresolvedKeyframes[i];
2028
- if (typeof keyframe === "string" &&
2029
- !invalidTemplates.has(keyframe) &&
2030
- analyseComplexValue(keyframe).values.length) {
2031
- animatableTemplate = unresolvedKeyframes[i];
2032
- }
2033
- i++;
2034
- }
2035
- if (animatableTemplate && name) {
2036
- for (const noneIndex of noneKeyframeIndexes) {
2037
- unresolvedKeyframes[noneIndex] = getAnimatableNone(name, animatableTemplate);
2038
- }
2039
- }
2040
- }
2038
+ const findDimensionValueType = (v) => dimensionValueTypes.find(testValueType(v));
2041
2039
 
2042
2040
  class DOMKeyframesResolver extends KeyframeResolver {
2043
2041
  constructor(unresolvedKeyframes, onComplete, name, motionValue, element) {
@@ -3002,8 +3000,9 @@ function interpolate(input, output, { clamp: isClamp = true, ease, mixer } = {})
3002
3000
  */
3003
3001
  if (inputLength === 1)
3004
3002
  return () => output[0];
3005
- if (inputLength === 2 && input[0] === input[1])
3003
+ if (inputLength === 2 && output[0] === output[1])
3006
3004
  return () => output[1];
3005
+ const isZeroDeltaRange = input[0] === input[1];
3007
3006
  // If input runs highest -> lowest, reverse both arrays
3008
3007
  if (input[0] > input[inputLength - 1]) {
3009
3008
  input = [...input].reverse();
@@ -3012,6 +3011,8 @@ function interpolate(input, output, { clamp: isClamp = true, ease, mixer } = {})
3012
3011
  const mixers = createMixers(output, ease, mixer);
3013
3012
  const numMixers = mixers.length;
3014
3013
  const interpolator = (v) => {
3014
+ if (isZeroDeltaRange && v < input[0])
3015
+ return output[0];
3015
3016
  let i = 0;
3016
3017
  if (numMixers > 1) {
3017
3018
  for (; i < input.length - 2; i++) {
@@ -3995,7 +3996,7 @@ function animateTarget(visualElement, targetAndTransition, { delay = 0, transiti
3995
3996
  }
3996
3997
  }
3997
3998
  addValueToWillChange(visualElement, key);
3998
- value.start(animateMotionValue(key, value, valueTarget, visualElement.shouldReduceMotion && transformProps.has(key)
3999
+ value.start(animateMotionValue(key, value, valueTarget, visualElement.shouldReduceMotion && positionalKeys.has(key)
3999
4000
  ? { type: false }
4000
4001
  : valueTransition, visualElement, isHandoff));
4001
4002
  const animation = value.animation;
@@ -9161,6 +9162,17 @@ function initPrefersReducedMotion() {
9161
9162
  }
9162
9163
  }
9163
9164
 
9165
+ /**
9166
+ * A list of all ValueTypes
9167
+ */
9168
+ const valueTypes = [...dimensionValueTypes, color, complex];
9169
+ /**
9170
+ * Tests a value against the list of ValueTypes
9171
+ */
9172
+ const findValueType = (v) => valueTypes.find(testValueType(v));
9173
+
9174
+ const visualElementStore = new WeakMap();
9175
+
9164
9176
  function updateMotionValuesFromProps(element, next, prev) {
9165
9177
  for (const key in next) {
9166
9178
  const nextValue = next[key];
@@ -9176,7 +9188,7 @@ function updateMotionValuesFromProps(element, next, prev) {
9176
9188
  * and warn against mismatches.
9177
9189
  */
9178
9190
  if (process.env.NODE_ENV === "development") {
9179
- warnOnce(nextValue.version === "11.16.4", `Attempting to mix Motion versions ${nextValue.version} with 11.16.4 may not work as expected.`);
9191
+ warnOnce(nextValue.version === "11.16.7", `Attempting to mix Motion versions ${nextValue.version} with 11.16.7 may not work as expected.`);
9180
9192
  }
9181
9193
  }
9182
9194
  else if (isMotionValue(prevValue)) {
@@ -9215,17 +9227,6 @@ function updateMotionValuesFromProps(element, next, prev) {
9215
9227
  return next;
9216
9228
  }
9217
9229
 
9218
- const visualElementStore = new WeakMap();
9219
-
9220
- /**
9221
- * A list of all ValueTypes
9222
- */
9223
- const valueTypes = [...dimensionValueTypes, color, complex];
9224
- /**
9225
- * Tests a value against the list of ValueTypes
9226
- */
9227
- const findValueType = (v) => valueTypes.find(testValueType(v));
9228
-
9229
9230
  const propEventHandlers = [
9230
9231
  "AnimationStart",
9231
9232
  "AnimationComplete",