From 28a2d198f242ba5a88a98d1d9174a0ade9e1b472 Mon Sep 17 00:00:00 2001 From: Nick Lefever Date: Thu, 2 Oct 2025 17:48:26 -0700 Subject: [PATCH 1/2] Add toDynamic conversion for ValueUnit and ColorStop (#54039) Summary: Adding toDynamic conversion to `ColorStop` and `ValueUnit` structs which are being used by the linear and radial gradient data structures. Changelog: [Internal] Reviewed By: christophpurrer Differential Revision: D83788006 --- .../react/renderer/graphics/ColorStop.h | 9 +++++++++ .../react/renderer/graphics/ValueUnit.h | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/ColorStop.h b/packages/react-native/ReactCommon/react/renderer/graphics/ColorStop.h index 968c2758cf1a..eeb51511430a 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/ColorStop.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/ColorStop.h @@ -17,6 +17,15 @@ struct ColorStop { bool operator==(const ColorStop& other) const = default; SharedColor color; ValueUnit position; + +#ifdef RN_SERIALIZABLE_STATE + folly::dynamic toDynamic() const { + folly::dynamic result = folly::dynamic::object(); + result["color"] = *color; + result["position"] = position.toDynamic(); + return result; + } +#endif }; struct ProcessedColorStop { diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/ValueUnit.h b/packages/react-native/ReactCommon/react/renderer/graphics/ValueUnit.h index 4777ef3f217e..9e9914aad2e5 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/ValueUnit.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/ValueUnit.h @@ -7,6 +7,10 @@ #pragma once +#ifdef RN_SERIALIZABLE_STATE +#include +#endif + namespace facebook::react { enum class UnitType { @@ -44,5 +48,18 @@ struct ValueUnit { constexpr operator bool() const { return unit != UnitType::Undefined; } + +#ifdef RN_SERIALIZABLE_STATE + folly::dynamic toDynamic() const { + switch (unit) { + case UnitType::Undefined: + return nullptr; + case UnitType::Point: + return value; + case UnitType::Percent: + return std::format("{}%", value); + } + } +#endif }; } // namespace facebook::react From ecf69934d718c0f3362637e21d90a3b794a042a9 Mon Sep 17 00:00:00 2001 From: Nick Lefever Date: Thu, 2 Oct 2025 17:48:26 -0700 Subject: [PATCH 2/2] Add toDynamic conversion for LinearGradient (#54040) Summary: Implement toDynamic conversion of the LinearGradient following the parse logic as described here: https://www.internalfb.com/code/fbsource/[5fa7eb2b733a]/xplat/js/react-native-github/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/LinearGradient.kt?lines=24-76 Changelog: [Internal] Reviewed By: christophpurrer Differential Revision: D83788005 --- .../react/renderer/graphics/LinearGradient.h | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/LinearGradient.h b/packages/react-native/ReactCommon/react/renderer/graphics/LinearGradient.h index 8c0a654d3ef8..5cab7f05ed1e 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/LinearGradient.h +++ b/packages/react-native/ReactCommon/react/renderer/graphics/LinearGradient.h @@ -18,6 +18,18 @@ namespace facebook::react { enum class GradientDirectionType { Angle, Keyword }; +inline std::string toString( + const GradientDirectionType& gradientDirectionType) { + switch (gradientDirectionType) { + case GradientDirectionType::Angle: + return "angle"; + case GradientDirectionType::Keyword: + return "keyword"; + } + + return ""; +} + enum class GradientKeyword { ToTopRight, ToBottomRight, @@ -25,6 +37,21 @@ enum class GradientKeyword { ToBottomLeft, }; +inline std::string toString(const GradientKeyword& gradientKeyword) { + switch (gradientKeyword) { + case GradientKeyword::ToTopRight: + return "to top right"; + case GradientKeyword::ToBottomRight: + return "to bottom right"; + case GradientKeyword::ToTopLeft: + return "to top left"; + case GradientKeyword::ToBottomLeft: + return "to bottom left"; + } + + return ""; +} + struct GradientDirection { GradientDirectionType type; std::variant value; @@ -32,6 +59,20 @@ struct GradientDirection { bool operator==(const GradientDirection& other) const { return type == other.type && value == other.value; } + +#ifdef RN_SERIALIZABLE_STATE + folly::dynamic toDynamic() const { + folly::dynamic result = folly::dynamic::object(); + result["type"] = toString(type); + + if (std::holds_alternative(value)) { + result["value"] = std::get(value); + } else if (std::holds_alternative(value)) { + result["value"] = toString(std::get(value)); + } + return result; + } +#endif }; struct LinearGradient { @@ -41,6 +82,21 @@ struct LinearGradient { bool operator==(const LinearGradient& other) const { return direction == other.direction && colorStops == other.colorStops; } + +#ifdef RN_SERIALIZABLE_STATE + folly::dynamic toDynamic() const { + folly::dynamic result = folly::dynamic::object(); + result["type"] = "linear-gradient"; + result["direction"] = direction.toDynamic(); + + folly::dynamic colorStopsArray = folly::dynamic::array(); + for (const auto& colorStop : colorStops) { + colorStopsArray.push_back(colorStop.toDynamic()); + } + result["colorStops"] = colorStopsArray; + return result; + } +#endif }; inline GradientKeyword parseGradientKeyword(const std::string& keyword) {