Implement prop diffing for transform props in <View> (#48832)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/48832

This diff implements the diffing for transform props of <View>

changelog: [internal] internal

Reviewed By: javache

Differential Revision: D59972039

fbshipit-source-id: e4c3beff4c6411595ab83ff62b54b948f9337851
This commit is contained in:
David Vacca
2025-01-22 12:07:06 -08:00
committed by Facebook GitHub Bot
parent 9a5e365865
commit 2e8720af44
@@ -333,6 +333,69 @@ static void updateBorderColorsProps(
oldBorderColor.blockStart);
}
inline static void updateTransformOperationValue(
const std::string& operationName,
const ValueUnit& valueUnit,
folly::dynamic& resultTranslateArray) {
folly::dynamic resultTranslate = folly::dynamic::object();
if (valueUnit.unit == UnitType::Percent) {
resultTranslate[operationName] = std::to_string(valueUnit.value) + "%";
} else {
resultTranslate[operationName] = valueUnit.value;
}
resultTranslateArray.push_back(std::move(resultTranslate));
}
inline static void updateTransformProps(
const Transform& transform,
const TransformOperation& operation,
folly::dynamic& resultTranslateArray) {
// See serialization rules in:
// react-native-github/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h?lines=592
std::string operationName;
switch (operation.type) {
case TransformOperationType::Scale:
operationName = "scale";
if (operation.x == operation.y && operation.x == operation.z) {
updateTransformOperationValue(
operationName, operation.x, resultTranslateArray);
return;
}
break;
case TransformOperationType::Translate:
operationName = "translate";
break;
case TransformOperationType::Rotate:
operationName = "rotate";
break;
case TransformOperationType::Perspective:
operationName = "perspective";
break;
case TransformOperationType::Arbitrary:
operationName = "matrix";
resultTranslateArray[operationName] = transform;
break;
case TransformOperationType::Identity:
// Do nothing
break;
case TransformOperationType::Skew:
operationName = "skew";
break;
}
if (operation.x.value != 0) {
updateTransformOperationValue(
operationName + "X", operation.x, resultTranslateArray);
}
if (operation.y.value != 0) {
updateTransformOperationValue(
operationName + "Y", operation.y, resultTranslateArray);
}
if (operation.z.value != 0) {
updateTransformOperationValue(
operationName + "Z", operation.z, resultTranslateArray);
}
}
folly::dynamic HostPlatformViewProps::getDiffProps(
const Props* prevProps) const {
folly::dynamic result = folly::dynamic::object();
@@ -629,6 +692,20 @@ folly::dynamic HostPlatformViewProps::getDiffProps(
updateBorderRadiusProps(result, borderRadii, oldProps->borderRadii);
}
// Transforms
if (transform != oldProps->transform ||
transformOrigin != oldProps->transformOrigin) {
folly::dynamic resultTranslateArray = folly::dynamic::array();
for (const auto& operation : transform.operations) {
updateTransformProps(transform, operation, resultTranslateArray);
}
result["transform"] = std::move(resultTranslateArray);
}
if (transformOrigin != oldProps->transformOrigin) {
result["transformOrigin"] = transformOrigin;
}
return result;
}