@tamagui/animations-react-native 3.0.0-beta.1313.1 → 3.0.0-beta.1341.1

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.
@@ -73,6 +73,14 @@ var layoutStyleKey = {
73
73
  minWidth: true,
74
74
  maxWidth: true
75
75
  };
76
+ var textMetricStyleKey = {
77
+ fontSize: true,
78
+ lineHeight: true
79
+ };
80
+ var jsDriverStyleKey = {
81
+ ...layoutStyleKey,
82
+ ...textMetricStyleKey
83
+ };
76
84
  function hasAnimatedLayoutKey(style, isDark, resolved) {
77
85
  for (var key in layoutStyleKey) {
78
86
  if (!(0, import_animation_helpers.getTransitionForKey)(resolved, key)) continue;
@@ -80,6 +88,16 @@ function hasAnimatedLayoutKey(style, isDark, resolved) {
80
88
  }
81
89
  return false;
82
90
  }
91
+ var getLeadingRatio = function(metrics) {
92
+ var ratio = metrics === null || metrics === void 0 ? void 0 : metrics.lineHeight;
93
+ return typeof ratio === "number" && Number.isFinite(ratio) && ratio >= 0 ? ratio : void 0;
94
+ };
95
+ var paintsLeadingProduct = function(style, ratio) {
96
+ return ratio !== void 0 && typeof style.fontSize === "number" && typeof style.lineHeight === "number";
97
+ };
98
+ var inheritedFontSizeNode = function(style, ratio, inheritedText) {
99
+ return ratio !== void 0 && typeof style.fontSize !== "number" && (inheritedText === null || inheritedText === void 0 ? void 0 : inheritedText.driver) === "react-native" ? inheritedText.fontSize : void 0;
100
+ };
83
101
  function isAnimatableColor(value) {
84
102
  return typeof value === "string" && (0, import_react_native.processColor)(value) != null;
85
103
  }
@@ -98,6 +116,7 @@ var costlyToAnimateStyleKey = {
98
116
  };
99
117
  var AnimatedView = import_react_native.Animated.View;
100
118
  var AnimatedText = import_react_native.Animated.Text;
119
+ var animatedTextInput;
101
120
  function useAnimatedNumber(initial) {
102
121
  var state = import_react.default.useRef(null);
103
122
  if (!state.current) {
@@ -213,8 +232,31 @@ function createAnimations(animations, options) {
213
232
  useAnimatedNumbersStyle,
214
233
  usePresence: import_use_presence.usePresence,
215
234
  ResetPresence: import_use_presence.ResetPresence,
235
+ useTextMetrics: function(param) {
236
+ var { inheritedText, lineHeight } = param;
237
+ var node = (inheritedText === null || inheritedText === void 0 ? void 0 : inheritedText.driver) === "react-native" ? inheritedText.fontSize : null;
238
+ var ratio = typeof lineHeight === "number" ? lineHeight : null;
239
+ var style = import_react.default.useMemo(function() {
240
+ return node ? ratio === null ? { fontSize: node } : {
241
+ fontSize: node,
242
+ lineHeight: import_react_native.Animated.multiply(node, ratio)
243
+ } : null;
244
+ }, [node, ratio]);
245
+ var textChannel = inheritedText !== null && inheritedText !== void 0 ? inheritedText : null;
246
+ if (!style) return {
247
+ style: null,
248
+ textChannel
249
+ };
250
+ animatedTextInput || (animatedTextInput = import_react_native.Animated.createAnimatedComponent(import_react_native.TextInput));
251
+ return {
252
+ style,
253
+ textChannel,
254
+ Text: AnimatedText,
255
+ TextInput: animatedTextInput
256
+ };
257
+ },
216
258
  useAnimations: function(param) {
217
- var { props, onTransition, style, componentState, presence, stateRef, styleState, useStyleEmitter } = param;
259
+ var { props, onTransition, style, componentState, presence, stateRef, styleState, useStyleEmitter, inheritedText } = param;
218
260
  var _themeState_name;
219
261
  var isDisabled = import_constants.isWeb && componentState.unmounted === true;
220
262
  var isExiting = (presence === null || presence === void 0 ? void 0 : presence[0]) === false;
@@ -237,6 +279,36 @@ function createAnimations(animations, options) {
237
279
  var [, themeState] = (0, import_internal_runtime.useThemeWithState)({});
238
280
  var isDark = (themeState === null || themeState === void 0 ? void 0 : themeState.scheme) === "dark" || (themeState === null || themeState === void 0 ? void 0 : (_themeState_name = themeState.name) === null || _themeState_name === void 0 ? void 0 : _themeState_name.startsWith("dark"));
239
281
  var animateStyles = import_react.default.useRef({});
282
+ var leadingRatioValue = import_react.default.useRef(null);
283
+ var leadingRatioRef = import_react.default.useRef(void 0);
284
+ var paintsDerivedLeading = import_react.default.useRef(false);
285
+ var textChannelRef = import_react.default.useRef(null);
286
+ leadingRatioRef.current = getLeadingRatio(styleState === null || styleState === void 0 ? void 0 : styleState.nativeTextMetrics);
287
+ var paintedTextRef = import_react.default.useRef({});
288
+ var movesTextValue = function(key, target) {
289
+ if (typeof target !== "number") return false;
290
+ var node = animateStyles.current[key];
291
+ var last = node ? node["_value"] : paintedTextRef.current[key];
292
+ return last !== void 0 && last !== target;
293
+ };
294
+ var movesLeadingRatio = function(ratio) {
295
+ if (ratio === void 0) return false;
296
+ var node = leadingRatioValue.current;
297
+ var last = node ? node["_value"] : paintedTextRef.current.ratio;
298
+ return last !== void 0 && last !== ratio;
299
+ };
300
+ var fontSizeNode = import_react.default.useRef(null);
301
+ var animatedValueFor = function(key) {
302
+ var painted = animateStyles.current[key];
303
+ if (painted) return painted;
304
+ if (key === "fontSize" && fontSizeNode.current) return fontSizeNode.current;
305
+ if (textMetricStyleKey[key]) return new import_react_native.Animated.Value(paintedTextRef.current[key]);
306
+ return void 0;
307
+ };
308
+ var leadingRatioValueFrom = function() {
309
+ var _leadingRatioValue_current;
310
+ return (_leadingRatioValue_current = leadingRatioValue.current) !== null && _leadingRatioValue_current !== void 0 ? _leadingRatioValue_current : new import_react_native.Animated.Value(paintedTextRef.current.ratio);
311
+ };
240
312
  var animatedTranforms = import_react.default.useRef([]);
241
313
  var animationsState = import_react.default.useRef(/* @__PURE__ */ new WeakMap());
242
314
  var pseudoActiveRef = import_react.default.useRef(false);
@@ -270,18 +342,38 @@ function createAnimations(animations, options) {
270
342
  isExiting,
271
343
  !!onTransition,
272
344
  isDark,
273
- justFinishedEntering
345
+ justFinishedEntering,
346
+ leadingRatioRef.current,
347
+ inheritedText
274
348
  ];
275
349
  var res = import_react.default.useMemo(function() {
350
+ var _textChannelRef_current;
276
351
  var runners = [];
277
352
  var completions = [];
278
353
  var animationState = isExiting ? "exit" : isEntering || justFinishedEntering ? "enter" : "default";
279
354
  var resolved = (0, import_animation_helpers.forAnimationState)((0, import_animation_helpers.resolveTransition)(effectiveTransition, { animations }), animationState);
280
355
  var nonAnimatedStyle = {};
281
- var useNativeDriverForNode = nativeDriver && !hasAnimatedLayoutKey(style, isDark, resolved);
356
+ var paintedRatio = leadingRatioRef.current;
357
+ var paintsProduct = paintsLeadingProduct(style, paintedRatio);
358
+ var movesFontSize = movesTextValue("fontSize", style.fontSize);
359
+ var movesLeading = paintsProduct ? movesLeadingRatio(paintedRatio) : movesTextValue("lineHeight", style.lineHeight);
360
+ if (!isExiting && !isDisabled && !pseudoActiveRef.current) {
361
+ if (!movesFontSize) delete animateStyles.current.fontSize;
362
+ if (!movesLeading) delete animateStyles.current.lineHeight;
363
+ }
364
+ if (isDisabled || typeof style.fontSize !== "number" || !(0, import_animation_helpers.getTransitionForKey)(resolved, "fontSize")) {
365
+ fontSizeNode.current = null;
366
+ } else if (!fontSizeNode.current) {
367
+ fontSizeNode.current = new import_react_native.Animated.Value(style.fontSize);
368
+ }
282
369
  var seenAnimateKeys = /* @__PURE__ */ new Set();
283
370
  var sawTransform = false;
284
371
  var transformCount = 0;
372
+ var derivesLeading = !isDisabled && paintsProduct && (movesFontSize || movesLeading) && (!!(0, import_animation_helpers.getTransitionForKey)(resolved, "fontSize") || !!(0, import_animation_helpers.getTransitionForKey)(resolved, "lineHeight"));
373
+ var inheritedFontSize = isDisabled ? void 0 : inheritedFontSizeNode(style, paintedRatio, inheritedText);
374
+ var useNativeDriverForNode = nativeDriver && !hasAnimatedLayoutKey(style, isDark, resolved) && !movesFontSize && !movesLeading && !inheritedFontSize && !Object.keys(animateStyles.current).some(function(key2) {
375
+ return jsDriverStyleKey[key2];
376
+ });
285
377
  for (var key in style) {
286
378
  var rawVal = style[key];
287
379
  var val = resolveDynamicValue(rawVal, isDark);
@@ -289,7 +381,17 @@ function createAnimations(animations, options) {
289
381
  if (isDisabled) {
290
382
  continue;
291
383
  }
292
- if (animatedStyleKey[key] == null && !costlyToAnimateStyleKey[key] && !layoutStyleKey[key]) {
384
+ if ((derivesLeading || inheritedFontSize) && (key === "fontSize" || key === "lineHeight")) {
385
+ if (key === "fontSize" && derivesLeading && !movesFontSize) {
386
+ nonAnimatedStyle[key] = val;
387
+ }
388
+ continue;
389
+ }
390
+ if (textMetricStyleKey[key] && !(key === "fontSize" ? movesFontSize : movesLeading)) {
391
+ nonAnimatedStyle[key] = val;
392
+ continue;
393
+ }
394
+ if (animatedStyleKey[key] == null && !costlyToAnimateStyleKey[key] && !jsDriverStyleKey[key]) {
293
395
  nonAnimatedStyle[key] = val;
294
396
  continue;
295
397
  }
@@ -297,7 +399,7 @@ function createAnimations(animations, options) {
297
399
  nonAnimatedStyle[key] = val;
298
400
  continue;
299
401
  }
300
- if (layoutStyleKey[key] && typeof val !== "number") {
402
+ if (jsDriverStyleKey[key] && typeof val !== "number") {
301
403
  nonAnimatedStyle[key] = val;
302
404
  continue;
303
405
  }
@@ -306,7 +408,7 @@ function createAnimations(animations, options) {
306
408
  continue;
307
409
  }
308
410
  if (key !== "transform") {
309
- animateStyles.current[key] = update(key, animateStyles.current[key], val);
411
+ animateStyles.current[key] = update(key, animatedValueFor(key), val);
310
412
  seenAnimateKeys.add(key);
311
413
  continue;
312
414
  }
@@ -343,6 +445,35 @@ function createAnimations(animations, options) {
343
445
  }
344
446
  }
345
447
  }
448
+ var ratioFactor = function() {
449
+ if (!movesLeading) {
450
+ leadingRatioValue.current = null;
451
+ return paintedRatio;
452
+ }
453
+ leadingRatioValue.current = update("lineHeight", leadingRatioValueFrom(), paintedRatio);
454
+ return leadingRatioValue.current;
455
+ };
456
+ var derivedLeading;
457
+ if (derivesLeading) {
458
+ var fontSizeFactor = style.fontSize;
459
+ if (movesFontSize) {
460
+ fontSizeFactor = update("fontSize", animatedValueFor("fontSize"), style.fontSize);
461
+ animateStyles.current.fontSize = fontSizeFactor;
462
+ seenAnimateKeys.add("fontSize");
463
+ }
464
+ derivedLeading = import_react_native.Animated.multiply(fontSizeFactor, ratioFactor());
465
+ } else if (inheritedFontSize) {
466
+ derivedLeading = import_react_native.Animated.multiply(inheritedFontSize, ratioFactor());
467
+ } else if (!isDisabled) {
468
+ leadingRatioValue.current = null;
469
+ }
470
+ paintsDerivedLeading.current = !!derivedLeading;
471
+ var ownFontSizeNode = fontSizeNode.current;
472
+ var textChannel = ownFontSizeNode ? ((_textChannelRef_current = textChannelRef.current) === null || _textChannelRef_current === void 0 ? void 0 : _textChannelRef_current.fontSize) === ownFontSizeNode ? textChannelRef.current : {
473
+ fontSize: ownFontSizeNode,
474
+ driver: "react-native"
475
+ } : typeof style.fontSize === "number" ? null : inheritedText !== null && inheritedText !== void 0 ? inheritedText : null;
476
+ textChannelRef.current = textChannel;
346
477
  if (!isExiting && !isDisabled && !pseudoActiveRef.current) {
347
478
  for (var k in animateStyles.current) {
348
479
  if (!seenAnimateKeys.has(k)) delete animateStyles.current[k];
@@ -365,11 +496,20 @@ function createAnimations(animations, options) {
365
496
  var _animationsState_current_get;
366
497
  return [k2, ((_animationsState_current_get = animationsState.current.get(v)) === null || _animationsState_current_get === void 0 ? void 0 : _animationsState_current_get.interpolation) || v];
367
498
  })),
499
+ ...derivedLeading ? { lineHeight: derivedLeading } : null,
368
500
  ...animatedTransformStyle
369
501
  };
502
+ if (!isDisabled) {
503
+ paintedTextRef.current = {
504
+ fontSize: style.fontSize,
505
+ lineHeight: style.lineHeight,
506
+ ratio: paintedRatio
507
+ };
508
+ }
370
509
  return {
371
510
  runners,
372
511
  completions,
512
+ textChannel,
373
513
  style: [nonAnimatedStyle, animatedStyle]
374
514
  };
375
515
  function update(key2, animated, valIn) {
@@ -509,20 +649,31 @@ function createAnimations(animations, options) {
509
649
  }
510
650
  });
511
651
  }, args);
512
- useStyleEmitter === null || useStyleEmitter === void 0 ? void 0 : useStyleEmitter(function(nextStyle, emittedTransition, pseudoActive) {
652
+ var onEmittedStyle = function(nextStyle, emittedTransition, pseudoActive, nextMetrics) {
513
653
  pseudoActiveRef.current = pseudoActive === true;
514
654
  var runners = [];
515
655
  var seenAnimateKeys = /* @__PURE__ */ new Set();
516
656
  var transformCount = 0;
517
657
  var animatedShapeChanged = false;
518
658
  var emittedResolved = (0, import_animation_helpers.forAnimationState)((0, import_animation_helpers.resolveTransition)(emittedTransition !== null && emittedTransition !== void 0 ? emittedTransition : effectiveTransition, { animations }), "default");
519
- var useNativeDriverForNode = nativeDriver && !hasAnimatedLayoutKey(nextStyle, isDark, emittedResolved) && !Object.keys(animateStyles.current).some(function(key2) {
520
- return layoutStyleKey[key2];
659
+ var emittedRatio = getLeadingRatio(nextMetrics);
660
+ var emitterPaintsProduct = paintsLeadingProduct(nextStyle, emittedRatio);
661
+ var emitterMovesFontSize = movesTextValue("fontSize", nextStyle.fontSize);
662
+ var emitterMovesLeading = emitterPaintsProduct ? movesLeadingRatio(emittedRatio) : movesTextValue("lineHeight", nextStyle.lineHeight);
663
+ var useNativeDriverForNode = nativeDriver && !hasAnimatedLayoutKey(nextStyle, isDark, emittedResolved) && !emitterMovesFontSize && !emitterMovesLeading && !inheritedFontSizeNode(nextStyle, emittedRatio, inheritedText) && !Object.keys(animateStyles.current).some(function(key2) {
664
+ return jsDriverStyleKey[key2];
521
665
  });
666
+ var emitterDerivesLeading = emitterPaintsProduct && (emitterMovesFontSize || emitterMovesLeading) && (!!(0, import_animation_helpers.getTransitionForKey)(emittedResolved, "fontSize") || !!(0, import_animation_helpers.getTransitionForKey)(emittedResolved, "lineHeight"));
522
667
  for (var key in nextStyle) {
523
668
  var rawVal = nextStyle[key];
524
669
  var val = resolveDynamicValue(rawVal, isDark);
525
670
  if (val === void 0) continue;
671
+ if (emitterDerivesLeading && (key === "fontSize" || key === "lineHeight")) {
672
+ continue;
673
+ }
674
+ if (textMetricStyleKey[key] && !(key === "fontSize" ? emitterMovesFontSize : emitterMovesLeading)) {
675
+ continue;
676
+ }
526
677
  if (key === "transform" && Array.isArray(val)) {
527
678
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
528
679
  try {
@@ -550,14 +701,28 @@ function createAnimations(animations, options) {
550
701
  }
551
702
  }
552
703
  }
553
- } else if (animatedStyleKey[key] != null || costlyToAnimateStyleKey[key] || layoutStyleKey[key]) {
554
- if (layoutStyleKey[key] && typeof val !== "number") continue;
704
+ } else if (animatedStyleKey[key] != null || costlyToAnimateStyleKey[key] || jsDriverStyleKey[key]) {
705
+ if (jsDriverStyleKey[key] && typeof val !== "number") continue;
555
706
  if (colorStyleKey[key] && !isAnimatableColor(val)) continue;
556
707
  if (!animateStyles.current[key]) animatedShapeChanged = true;
557
- animateStyles.current[key] = update(key, animateStyles.current[key], val);
708
+ animateStyles.current[key] = update(key, animatedValueFor(key), val);
558
709
  seenAnimateKeys.add(key);
559
710
  }
560
711
  }
712
+ if (emitterDerivesLeading) {
713
+ if (emitterMovesFontSize) {
714
+ if (!animateStyles.current.fontSize) animatedShapeChanged = true;
715
+ animateStyles.current.fontSize = update("fontSize", animatedValueFor("fontSize"), nextStyle.fontSize);
716
+ seenAnimateKeys.add("fontSize");
717
+ }
718
+ if (emitterMovesLeading) {
719
+ if (!leadingRatioValue.current) animatedShapeChanged = true;
720
+ leadingRatioValue.current = update("lineHeight", leadingRatioValueFrom(), emittedRatio);
721
+ }
722
+ }
723
+ if (emitterDerivesLeading !== paintsDerivedLeading.current) {
724
+ animatedShapeChanged = true;
725
+ }
561
726
  for (var key1 in animateStyles.current) {
562
727
  if (!seenAnimateKeys.has(key1)) {
563
728
  delete animateStyles.current[key1];
@@ -568,6 +733,11 @@ function createAnimations(animations, options) {
568
733
  animatedTranforms.current = animatedTranforms.current.slice(0, transformCount);
569
734
  animatedShapeChanged = true;
570
735
  }
736
+ paintedTextRef.current = {
737
+ fontSize: nextStyle.fontSize,
738
+ lineHeight: nextStyle.lineHeight,
739
+ ratio: emittedRatio
740
+ };
571
741
  runners.forEach(function(r) {
572
742
  return r();
573
743
  });
@@ -609,7 +779,8 @@ function createAnimations(animations, options) {
609
779
  });
610
780
  return value;
611
781
  }
612
- });
782
+ };
783
+ useStyleEmitter === null || useStyleEmitter === void 0 ? void 0 : useStyleEmitter(onEmittedStyle);
613
784
  if (process.env.NODE_ENV === "development") {
614
785
  if (props["debug"] === "verbose") {
615
786
  console.info(`Animated`, {
@@ -73,6 +73,14 @@ var layoutStyleKey = {
73
73
  minWidth: true,
74
74
  maxWidth: true
75
75
  };
76
+ var textMetricStyleKey = {
77
+ fontSize: true,
78
+ lineHeight: true
79
+ };
80
+ var jsDriverStyleKey = {
81
+ ...layoutStyleKey,
82
+ ...textMetricStyleKey
83
+ };
76
84
  function hasAnimatedLayoutKey(style, isDark, resolved) {
77
85
  for (var key in layoutStyleKey) {
78
86
  if (!(0, import_animation_helpers.getTransitionForKey)(resolved, key)) continue;
@@ -80,6 +88,16 @@ function hasAnimatedLayoutKey(style, isDark, resolved) {
80
88
  }
81
89
  return false;
82
90
  }
91
+ var getLeadingRatio = function(metrics) {
92
+ var ratio = metrics === null || metrics === void 0 ? void 0 : metrics.lineHeight;
93
+ return typeof ratio === "number" && Number.isFinite(ratio) && ratio >= 0 ? ratio : void 0;
94
+ };
95
+ var paintsLeadingProduct = function(style, ratio) {
96
+ return ratio !== void 0 && typeof style.fontSize === "number" && typeof style.lineHeight === "number";
97
+ };
98
+ var inheritedFontSizeNode = function(style, ratio, inheritedText) {
99
+ return ratio !== void 0 && typeof style.fontSize !== "number" && (inheritedText === null || inheritedText === void 0 ? void 0 : inheritedText.driver) === "react-native" ? inheritedText.fontSize : void 0;
100
+ };
83
101
  function isAnimatableColor(value) {
84
102
  return typeof value === "string" && (0, import_react_native.processColor)(value) != null;
85
103
  }
@@ -98,6 +116,7 @@ var costlyToAnimateStyleKey = {
98
116
  };
99
117
  var AnimatedView = import_react_native.Animated.View;
100
118
  var AnimatedText = import_react_native.Animated.Text;
119
+ var animatedTextInput;
101
120
  function useAnimatedNumber(initial) {
102
121
  var state = import_react.default.useRef(null);
103
122
  if (!state.current) {
@@ -213,8 +232,31 @@ function createAnimations(animations, options) {
213
232
  useAnimatedNumbersStyle,
214
233
  usePresence: import_use_presence.usePresence,
215
234
  ResetPresence: import_use_presence.ResetPresence,
235
+ useTextMetrics: function(param) {
236
+ var { inheritedText, lineHeight } = param;
237
+ var node = (inheritedText === null || inheritedText === void 0 ? void 0 : inheritedText.driver) === "react-native" ? inheritedText.fontSize : null;
238
+ var ratio = typeof lineHeight === "number" ? lineHeight : null;
239
+ var style = import_react.default.useMemo(function() {
240
+ return node ? ratio === null ? { fontSize: node } : {
241
+ fontSize: node,
242
+ lineHeight: import_react_native.Animated.multiply(node, ratio)
243
+ } : null;
244
+ }, [node, ratio]);
245
+ var textChannel = inheritedText !== null && inheritedText !== void 0 ? inheritedText : null;
246
+ if (!style) return {
247
+ style: null,
248
+ textChannel
249
+ };
250
+ animatedTextInput || (animatedTextInput = import_react_native.Animated.createAnimatedComponent(import_react_native.TextInput));
251
+ return {
252
+ style,
253
+ textChannel,
254
+ Text: AnimatedText,
255
+ TextInput: animatedTextInput
256
+ };
257
+ },
216
258
  useAnimations: function(param) {
217
- var { props, onTransition, style, componentState, presence, stateRef, styleState, useStyleEmitter } = param;
259
+ var { props, onTransition, style, componentState, presence, stateRef, styleState, useStyleEmitter, inheritedText } = param;
218
260
  var _themeState_name;
219
261
  var isDisabled = import_constants.isWeb && componentState.unmounted === true;
220
262
  var isExiting = (presence === null || presence === void 0 ? void 0 : presence[0]) === false;
@@ -237,6 +279,36 @@ function createAnimations(animations, options) {
237
279
  var [, themeState] = (0, import_internal_runtime.useThemeWithState)({});
238
280
  var isDark = (themeState === null || themeState === void 0 ? void 0 : themeState.scheme) === "dark" || (themeState === null || themeState === void 0 ? void 0 : (_themeState_name = themeState.name) === null || _themeState_name === void 0 ? void 0 : _themeState_name.startsWith("dark"));
239
281
  var animateStyles = import_react.default.useRef({});
282
+ var leadingRatioValue = import_react.default.useRef(null);
283
+ var leadingRatioRef = import_react.default.useRef(void 0);
284
+ var paintsDerivedLeading = import_react.default.useRef(false);
285
+ var textChannelRef = import_react.default.useRef(null);
286
+ leadingRatioRef.current = getLeadingRatio(styleState === null || styleState === void 0 ? void 0 : styleState.nativeTextMetrics);
287
+ var paintedTextRef = import_react.default.useRef({});
288
+ var movesTextValue = function(key, target) {
289
+ if (typeof target !== "number") return false;
290
+ var node = animateStyles.current[key];
291
+ var last = node ? node["_value"] : paintedTextRef.current[key];
292
+ return last !== void 0 && last !== target;
293
+ };
294
+ var movesLeadingRatio = function(ratio) {
295
+ if (ratio === void 0) return false;
296
+ var node = leadingRatioValue.current;
297
+ var last = node ? node["_value"] : paintedTextRef.current.ratio;
298
+ return last !== void 0 && last !== ratio;
299
+ };
300
+ var fontSizeNode = import_react.default.useRef(null);
301
+ var animatedValueFor = function(key) {
302
+ var painted = animateStyles.current[key];
303
+ if (painted) return painted;
304
+ if (key === "fontSize" && fontSizeNode.current) return fontSizeNode.current;
305
+ if (textMetricStyleKey[key]) return new import_react_native.Animated.Value(paintedTextRef.current[key]);
306
+ return void 0;
307
+ };
308
+ var leadingRatioValueFrom = function() {
309
+ var _leadingRatioValue_current;
310
+ return (_leadingRatioValue_current = leadingRatioValue.current) !== null && _leadingRatioValue_current !== void 0 ? _leadingRatioValue_current : new import_react_native.Animated.Value(paintedTextRef.current.ratio);
311
+ };
240
312
  var animatedTranforms = import_react.default.useRef([]);
241
313
  var animationsState = import_react.default.useRef(/* @__PURE__ */ new WeakMap());
242
314
  var pseudoActiveRef = import_react.default.useRef(false);
@@ -270,18 +342,38 @@ function createAnimations(animations, options) {
270
342
  isExiting,
271
343
  !!onTransition,
272
344
  isDark,
273
- justFinishedEntering
345
+ justFinishedEntering,
346
+ leadingRatioRef.current,
347
+ inheritedText
274
348
  ];
275
349
  var res = import_react.default.useMemo(function() {
350
+ var _textChannelRef_current;
276
351
  var runners = [];
277
352
  var completions = [];
278
353
  var animationState = isExiting ? "exit" : isEntering || justFinishedEntering ? "enter" : "default";
279
354
  var resolved = (0, import_animation_helpers.forAnimationState)((0, import_animation_helpers.resolveTransition)(effectiveTransition, { animations }), animationState);
280
355
  var nonAnimatedStyle = {};
281
- var useNativeDriverForNode = nativeDriver && !hasAnimatedLayoutKey(style, isDark, resolved);
356
+ var paintedRatio = leadingRatioRef.current;
357
+ var paintsProduct = paintsLeadingProduct(style, paintedRatio);
358
+ var movesFontSize = movesTextValue("fontSize", style.fontSize);
359
+ var movesLeading = paintsProduct ? movesLeadingRatio(paintedRatio) : movesTextValue("lineHeight", style.lineHeight);
360
+ if (!isExiting && !isDisabled && !pseudoActiveRef.current) {
361
+ if (!movesFontSize) delete animateStyles.current.fontSize;
362
+ if (!movesLeading) delete animateStyles.current.lineHeight;
363
+ }
364
+ if (isDisabled || typeof style.fontSize !== "number" || !(0, import_animation_helpers.getTransitionForKey)(resolved, "fontSize")) {
365
+ fontSizeNode.current = null;
366
+ } else if (!fontSizeNode.current) {
367
+ fontSizeNode.current = new import_react_native.Animated.Value(style.fontSize);
368
+ }
282
369
  var seenAnimateKeys = /* @__PURE__ */ new Set();
283
370
  var sawTransform = false;
284
371
  var transformCount = 0;
372
+ var derivesLeading = !isDisabled && paintsProduct && (movesFontSize || movesLeading) && (!!(0, import_animation_helpers.getTransitionForKey)(resolved, "fontSize") || !!(0, import_animation_helpers.getTransitionForKey)(resolved, "lineHeight"));
373
+ var inheritedFontSize = isDisabled ? void 0 : inheritedFontSizeNode(style, paintedRatio, inheritedText);
374
+ var useNativeDriverForNode = nativeDriver && !hasAnimatedLayoutKey(style, isDark, resolved) && !movesFontSize && !movesLeading && !inheritedFontSize && !Object.keys(animateStyles.current).some(function(key2) {
375
+ return jsDriverStyleKey[key2];
376
+ });
285
377
  for (var key in style) {
286
378
  var rawVal = style[key];
287
379
  var val = resolveDynamicValue(rawVal, isDark);
@@ -289,7 +381,17 @@ function createAnimations(animations, options) {
289
381
  if (isDisabled) {
290
382
  continue;
291
383
  }
292
- if (animatedStyleKey[key] == null && !costlyToAnimateStyleKey[key] && !layoutStyleKey[key]) {
384
+ if ((derivesLeading || inheritedFontSize) && (key === "fontSize" || key === "lineHeight")) {
385
+ if (key === "fontSize" && derivesLeading && !movesFontSize) {
386
+ nonAnimatedStyle[key] = val;
387
+ }
388
+ continue;
389
+ }
390
+ if (textMetricStyleKey[key] && !(key === "fontSize" ? movesFontSize : movesLeading)) {
391
+ nonAnimatedStyle[key] = val;
392
+ continue;
393
+ }
394
+ if (animatedStyleKey[key] == null && !costlyToAnimateStyleKey[key] && !jsDriverStyleKey[key]) {
293
395
  nonAnimatedStyle[key] = val;
294
396
  continue;
295
397
  }
@@ -297,7 +399,7 @@ function createAnimations(animations, options) {
297
399
  nonAnimatedStyle[key] = val;
298
400
  continue;
299
401
  }
300
- if (layoutStyleKey[key] && typeof val !== "number") {
402
+ if (jsDriverStyleKey[key] && typeof val !== "number") {
301
403
  nonAnimatedStyle[key] = val;
302
404
  continue;
303
405
  }
@@ -306,7 +408,7 @@ function createAnimations(animations, options) {
306
408
  continue;
307
409
  }
308
410
  if (key !== "transform") {
309
- animateStyles.current[key] = update(key, animateStyles.current[key], val);
411
+ animateStyles.current[key] = update(key, animatedValueFor(key), val);
310
412
  seenAnimateKeys.add(key);
311
413
  continue;
312
414
  }
@@ -343,6 +445,35 @@ function createAnimations(animations, options) {
343
445
  }
344
446
  }
345
447
  }
448
+ var ratioFactor = function() {
449
+ if (!movesLeading) {
450
+ leadingRatioValue.current = null;
451
+ return paintedRatio;
452
+ }
453
+ leadingRatioValue.current = update("lineHeight", leadingRatioValueFrom(), paintedRatio);
454
+ return leadingRatioValue.current;
455
+ };
456
+ var derivedLeading;
457
+ if (derivesLeading) {
458
+ var fontSizeFactor = style.fontSize;
459
+ if (movesFontSize) {
460
+ fontSizeFactor = update("fontSize", animatedValueFor("fontSize"), style.fontSize);
461
+ animateStyles.current.fontSize = fontSizeFactor;
462
+ seenAnimateKeys.add("fontSize");
463
+ }
464
+ derivedLeading = import_react_native.Animated.multiply(fontSizeFactor, ratioFactor());
465
+ } else if (inheritedFontSize) {
466
+ derivedLeading = import_react_native.Animated.multiply(inheritedFontSize, ratioFactor());
467
+ } else if (!isDisabled) {
468
+ leadingRatioValue.current = null;
469
+ }
470
+ paintsDerivedLeading.current = !!derivedLeading;
471
+ var ownFontSizeNode = fontSizeNode.current;
472
+ var textChannel = ownFontSizeNode ? ((_textChannelRef_current = textChannelRef.current) === null || _textChannelRef_current === void 0 ? void 0 : _textChannelRef_current.fontSize) === ownFontSizeNode ? textChannelRef.current : {
473
+ fontSize: ownFontSizeNode,
474
+ driver: "react-native"
475
+ } : typeof style.fontSize === "number" ? null : inheritedText !== null && inheritedText !== void 0 ? inheritedText : null;
476
+ textChannelRef.current = textChannel;
346
477
  if (!isExiting && !isDisabled && !pseudoActiveRef.current) {
347
478
  for (var k in animateStyles.current) {
348
479
  if (!seenAnimateKeys.has(k)) delete animateStyles.current[k];
@@ -365,11 +496,20 @@ function createAnimations(animations, options) {
365
496
  var _animationsState_current_get;
366
497
  return [k2, ((_animationsState_current_get = animationsState.current.get(v)) === null || _animationsState_current_get === void 0 ? void 0 : _animationsState_current_get.interpolation) || v];
367
498
  })),
499
+ ...derivedLeading ? { lineHeight: derivedLeading } : null,
368
500
  ...animatedTransformStyle
369
501
  };
502
+ if (!isDisabled) {
503
+ paintedTextRef.current = {
504
+ fontSize: style.fontSize,
505
+ lineHeight: style.lineHeight,
506
+ ratio: paintedRatio
507
+ };
508
+ }
370
509
  return {
371
510
  runners,
372
511
  completions,
512
+ textChannel,
373
513
  style: [nonAnimatedStyle, animatedStyle]
374
514
  };
375
515
  function update(key2, animated, valIn) {
@@ -509,20 +649,31 @@ function createAnimations(animations, options) {
509
649
  }
510
650
  });
511
651
  }, args);
512
- useStyleEmitter === null || useStyleEmitter === void 0 ? void 0 : useStyleEmitter(function(nextStyle, emittedTransition, pseudoActive) {
652
+ var onEmittedStyle = function(nextStyle, emittedTransition, pseudoActive, nextMetrics) {
513
653
  pseudoActiveRef.current = pseudoActive === true;
514
654
  var runners = [];
515
655
  var seenAnimateKeys = /* @__PURE__ */ new Set();
516
656
  var transformCount = 0;
517
657
  var animatedShapeChanged = false;
518
658
  var emittedResolved = (0, import_animation_helpers.forAnimationState)((0, import_animation_helpers.resolveTransition)(emittedTransition !== null && emittedTransition !== void 0 ? emittedTransition : effectiveTransition, { animations }), "default");
519
- var useNativeDriverForNode = nativeDriver && !hasAnimatedLayoutKey(nextStyle, isDark, emittedResolved) && !Object.keys(animateStyles.current).some(function(key2) {
520
- return layoutStyleKey[key2];
659
+ var emittedRatio = getLeadingRatio(nextMetrics);
660
+ var emitterPaintsProduct = paintsLeadingProduct(nextStyle, emittedRatio);
661
+ var emitterMovesFontSize = movesTextValue("fontSize", nextStyle.fontSize);
662
+ var emitterMovesLeading = emitterPaintsProduct ? movesLeadingRatio(emittedRatio) : movesTextValue("lineHeight", nextStyle.lineHeight);
663
+ var useNativeDriverForNode = nativeDriver && !hasAnimatedLayoutKey(nextStyle, isDark, emittedResolved) && !emitterMovesFontSize && !emitterMovesLeading && !inheritedFontSizeNode(nextStyle, emittedRatio, inheritedText) && !Object.keys(animateStyles.current).some(function(key2) {
664
+ return jsDriverStyleKey[key2];
521
665
  });
666
+ var emitterDerivesLeading = emitterPaintsProduct && (emitterMovesFontSize || emitterMovesLeading) && (!!(0, import_animation_helpers.getTransitionForKey)(emittedResolved, "fontSize") || !!(0, import_animation_helpers.getTransitionForKey)(emittedResolved, "lineHeight"));
522
667
  for (var key in nextStyle) {
523
668
  var rawVal = nextStyle[key];
524
669
  var val = resolveDynamicValue(rawVal, isDark);
525
670
  if (val === void 0) continue;
671
+ if (emitterDerivesLeading && (key === "fontSize" || key === "lineHeight")) {
672
+ continue;
673
+ }
674
+ if (textMetricStyleKey[key] && !(key === "fontSize" ? emitterMovesFontSize : emitterMovesLeading)) {
675
+ continue;
676
+ }
526
677
  if (key === "transform" && Array.isArray(val)) {
527
678
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
528
679
  try {
@@ -550,14 +701,28 @@ function createAnimations(animations, options) {
550
701
  }
551
702
  }
552
703
  }
553
- } else if (animatedStyleKey[key] != null || costlyToAnimateStyleKey[key] || layoutStyleKey[key]) {
554
- if (layoutStyleKey[key] && typeof val !== "number") continue;
704
+ } else if (animatedStyleKey[key] != null || costlyToAnimateStyleKey[key] || jsDriverStyleKey[key]) {
705
+ if (jsDriverStyleKey[key] && typeof val !== "number") continue;
555
706
  if (colorStyleKey[key] && !isAnimatableColor(val)) continue;
556
707
  if (!animateStyles.current[key]) animatedShapeChanged = true;
557
- animateStyles.current[key] = update(key, animateStyles.current[key], val);
708
+ animateStyles.current[key] = update(key, animatedValueFor(key), val);
558
709
  seenAnimateKeys.add(key);
559
710
  }
560
711
  }
712
+ if (emitterDerivesLeading) {
713
+ if (emitterMovesFontSize) {
714
+ if (!animateStyles.current.fontSize) animatedShapeChanged = true;
715
+ animateStyles.current.fontSize = update("fontSize", animatedValueFor("fontSize"), nextStyle.fontSize);
716
+ seenAnimateKeys.add("fontSize");
717
+ }
718
+ if (emitterMovesLeading) {
719
+ if (!leadingRatioValue.current) animatedShapeChanged = true;
720
+ leadingRatioValue.current = update("lineHeight", leadingRatioValueFrom(), emittedRatio);
721
+ }
722
+ }
723
+ if (emitterDerivesLeading !== paintsDerivedLeading.current) {
724
+ animatedShapeChanged = true;
725
+ }
561
726
  for (var key1 in animateStyles.current) {
562
727
  if (!seenAnimateKeys.has(key1)) {
563
728
  delete animateStyles.current[key1];
@@ -568,6 +733,11 @@ function createAnimations(animations, options) {
568
733
  animatedTranforms.current = animatedTranforms.current.slice(0, transformCount);
569
734
  animatedShapeChanged = true;
570
735
  }
736
+ paintedTextRef.current = {
737
+ fontSize: nextStyle.fontSize,
738
+ lineHeight: nextStyle.lineHeight,
739
+ ratio: emittedRatio
740
+ };
571
741
  runners.forEach(function(r) {
572
742
  return r();
573
743
  });
@@ -609,7 +779,8 @@ function createAnimations(animations, options) {
609
779
  });
610
780
  return value;
611
781
  }
612
- });
782
+ };
783
+ useStyleEmitter === null || useStyleEmitter === void 0 ? void 0 : useStyleEmitter(onEmittedStyle);
613
784
  if (process.env.NODE_ENV === "development") {
614
785
  if (props["debug"] === "verbose") {
615
786
  console.info(`Animated`, {