diff --git a/packages/react-native/Libraries/NativeComponent/BaseViewConfig.android.js b/packages/react-native/Libraries/NativeComponent/BaseViewConfig.android.js index c322077715d..407943c4c9d 100644 --- a/packages/react-native/Libraries/NativeComponent/BaseViewConfig.android.js +++ b/packages/react-native/Libraries/NativeComponent/BaseViewConfig.android.js @@ -10,7 +10,6 @@ import type {PartialViewConfigWithoutName} from './PlatformBaseViewConfig'; -import * as ReactNativeFeatureFlags from '../../src/private/featureflags/ReactNativeFeatureFlags'; import ReactNativeStyleAttributes from '../Components/View/ReactNativeStyleAttributes'; import {DynamicallyInjectedByGestureHandler} from './ViewConfigIgnore'; @@ -171,9 +170,7 @@ const validAttributesForNonEventProps = { process: require('../StyleSheet/processBackgroundImage').default, }, boxShadow: { - process: ReactNativeFeatureFlags.enableNativeCSSParsing() - ? undefined - : require('../StyleSheet/processBoxShadow').default, + process: require('../StyleSheet/processBoxShadow').default, }, filter: { process: require('../StyleSheet/processFilter').default, diff --git a/packages/react-native/Libraries/NativeComponent/BaseViewConfig.ios.js b/packages/react-native/Libraries/NativeComponent/BaseViewConfig.ios.js index bac309f7cf5..2cd155760db 100644 --- a/packages/react-native/Libraries/NativeComponent/BaseViewConfig.ios.js +++ b/packages/react-native/Libraries/NativeComponent/BaseViewConfig.ios.js @@ -10,7 +10,6 @@ import type {PartialViewConfigWithoutName} from './PlatformBaseViewConfig'; -import * as ReactNativeFeatureFlags from '../../src/private/featureflags/ReactNativeFeatureFlags'; import ReactNativeStyleAttributes from '../Components/View/ReactNativeStyleAttributes'; import { ConditionallyIgnoredEventHandlers, @@ -230,9 +229,7 @@ const validAttributesForNonEventProps = { process: require('../StyleSheet/processFilter').default, }, boxShadow: { - process: ReactNativeFeatureFlags.enableNativeCSSParsing() - ? undefined - : require('../StyleSheet/processBoxShadow').default, + process: require('../StyleSheet/processBoxShadow').default, }, mixBlendMode: true, isolation: true, diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewProps.cpp index b4218879c67..28e880f0e37 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewProps.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include #include diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/BoxShadowPropsConversions.h b/packages/react-native/ReactCommon/react/renderer/components/view/BoxShadowPropsConversions.h deleted file mode 100644 index 89d07939c08..00000000000 --- a/packages/react-native/ReactCommon/react/renderer/components/view/BoxShadowPropsConversions.h +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace facebook::react { - -inline void parseProcessedBoxShadow( - const PropsParserContext& context, - const RawValue& value, - std::vector& result) { - react_native_expect(value.hasType>()); - if (!value.hasType>()) { - result = {}; - return; - } - - std::vector boxShadows{}; - auto rawBoxShadows = static_cast>(value); - for (const auto& rawBoxShadow : rawBoxShadows) { - bool isMap = - rawBoxShadow.hasType>(); - react_native_expect(isMap); - if (!isMap) { - // If any box shadow is malformed then we should not apply any of them - // which is the web behavior. - result = {}; - return; - } - - auto rawBoxShadowMap = - static_cast>(rawBoxShadow); - BoxShadow boxShadow{}; - auto offsetX = rawBoxShadowMap.find("offsetX"); - react_native_expect(offsetX != rawBoxShadowMap.end()); - if (offsetX == rawBoxShadowMap.end()) { - result = {}; - return; - } - react_native_expect(offsetX->second.hasType()); - if (!offsetX->second.hasType()) { - result = {}; - return; - } - boxShadow.offsetX = (Float)offsetX->second; - - auto offsetY = rawBoxShadowMap.find("offsetY"); - react_native_expect(offsetY != rawBoxShadowMap.end()); - if (offsetY == rawBoxShadowMap.end()) { - result = {}; - return; - } - react_native_expect(offsetY->second.hasType()); - if (!offsetY->second.hasType()) { - result = {}; - return; - } - boxShadow.offsetY = (Float)offsetY->second; - - auto blurRadius = rawBoxShadowMap.find("blurRadius"); - if (blurRadius != rawBoxShadowMap.end()) { - react_native_expect(blurRadius->second.hasType()); - if (!blurRadius->second.hasType()) { - result = {}; - return; - } - boxShadow.blurRadius = (Float)blurRadius->second; - } - - auto spreadDistance = rawBoxShadowMap.find("spreadDistance"); - if (spreadDistance != rawBoxShadowMap.end()) { - react_native_expect(spreadDistance->second.hasType()); - if (!spreadDistance->second.hasType()) { - result = {}; - return; - } - boxShadow.spreadDistance = (Float)spreadDistance->second; - } - - auto inset = rawBoxShadowMap.find("inset"); - if (inset != rawBoxShadowMap.end()) { - react_native_expect(inset->second.hasType()); - if (!inset->second.hasType()) { - result = {}; - return; - } - boxShadow.inset = (bool)inset->second; - } - - auto color = rawBoxShadowMap.find("color"); - if (color != rawBoxShadowMap.end()) { - fromRawValue( - context.contextContainer, - context.surfaceId, - color->second, - boxShadow.color); - } - - boxShadows.push_back(boxShadow); - } - - result = boxShadows; -} - -inline SharedColor fromCSSColor(const CSSColor& cssColor) { - return hostPlatformColorFromRGBA( - cssColor.r, cssColor.g, cssColor.b, cssColor.a); -} - -inline std::optional fromCSSShadow(const CSSShadow& cssShadow) { - // TODO: handle non-px values - if (cssShadow.offsetX.unit != CSSLengthUnit::Px || - cssShadow.offsetY.unit != CSSLengthUnit::Px || - cssShadow.blurRadius.unit != CSSLengthUnit::Px || - cssShadow.spreadDistance.unit != CSSLengthUnit::Px) { - return {}; - } - - return BoxShadow{ - .offsetX = cssShadow.offsetX.value, - .offsetY = cssShadow.offsetY.value, - .blurRadius = cssShadow.blurRadius.value, - .spreadDistance = cssShadow.spreadDistance.value, - .color = fromCSSColor(cssShadow.color), - }; -} - -inline void parseUnprocessedBoxShadowString( - std::string&& value, - std::vector& result) { - auto boxShadowList = parseCSSProperty((std::string)value); - if (!std::holds_alternative(boxShadowList)) { - result = {}; - return; - } - - for (const auto& cssShadow : std::get(boxShadowList)) { - if (auto boxShadow = fromCSSShadow(cssShadow)) { - result.push_back(*boxShadow); - } else { - result = {}; - return; - } - } -} - -inline std::optional coerceLength(const RawValue& value) { - if (value.hasType()) { - return (Float)value; - } - - if (value.hasType()) { - auto len = parseCSSProperty((std::string)value); - if (!std::holds_alternative(len)) { - return {}; - } - - auto cssLen = std::get(len); - if (cssLen.unit != CSSLengthUnit::Px) { - return {}; - } - - return cssLen.value; - } - return {}; -} - -inline std::optional parseBoxShadowRawValue( - const PropsParserContext& context, - const RawValue& value) { - if (!value.hasType>()) { - return {}; - } - - auto boxShadow = std::unordered_map(value); - auto rawOffsetX = boxShadow.find("offsetX"); - if (rawOffsetX == boxShadow.end()) { - return {}; - } - auto offsetX = coerceLength(rawOffsetX->second); - if (!offsetX.has_value()) { - return {}; - } - - auto rawOffsetY = boxShadow.find("offsetY"); - if (rawOffsetY == boxShadow.end()) { - return {}; - } - auto offsetY = coerceLength(rawOffsetY->second); - if (!offsetY.has_value()) { - return {}; - } - - Float blurRadius = 0; - auto rawBlurRadius = boxShadow.find("blurRadius"); - if (rawBlurRadius != boxShadow.end()) { - if (auto blurRadiusValue = coerceLength(rawBlurRadius->second)) { - blurRadius = *blurRadiusValue; - } else { - return {}; - } - } - - Float spreadDistance = 0; - auto rawSpreadDistance = boxShadow.find("spreadDistance"); - if (rawSpreadDistance != boxShadow.end()) { - if (auto spreadDistanceValue = coerceLength(rawSpreadDistance->second)) { - spreadDistance = *spreadDistanceValue; - } else { - return {}; - } - } - - bool inset = false; - auto rawInset = boxShadow.find("inset"); - if (rawInset != boxShadow.end()) { - if (rawInset->second.hasType()) { - inset = (bool)rawInset->second; - } else { - return {}; - } - } - - SharedColor color; - auto rawColor = boxShadow.find("color"); - if (rawColor != boxShadow.end()) { - const auto& rawColorValue = rawColor->second; - if (rawColorValue.hasType()) { - auto cssColor = parseCSSProperty((std::string)rawColorValue); - if (!std::holds_alternative(cssColor)) { - return {}; - } - color = fromCSSColor(std::get(cssColor)); - } else { - fromRawValue( - context.contextContainer, context.surfaceId, rawColor->second, color); - if (!color) { - return {}; - } - } - } - - return BoxShadow{ - .offsetX = *offsetX, - .offsetY = *offsetY, - .blurRadius = blurRadius, - .spreadDistance = spreadDistance, - .color = color, - .inset = inset}; -} - -inline void parseUnprocessedBoxShadowList( - const PropsParserContext& context, - std::vector&& value, - std::vector& result) { - for (const auto& rawValue : value) { - if (auto boxShadow = parseBoxShadowRawValue(context, rawValue)) { - result.push_back(*boxShadow); - } else { - result = {}; - return; - } - } -} - -inline void parseUnprocessedBoxShadow( - const PropsParserContext& context, - const RawValue& value, - std::vector& result) { - if (value.hasType()) { - parseUnprocessedBoxShadowString((std::string)value, result); - } else if (value.hasType>()) { - parseUnprocessedBoxShadowList( - context, (std::vector)value, result); - } else { - result = {}; - } -} - -inline void fromRawValue( - const PropsParserContext& context, - const RawValue& value, - std::vector& result) { - if (ReactNativeFeatureFlags::enableNativeCSSParsing()) { - parseUnprocessedBoxShadow(context, value, result); - } else { - parseProcessedBoxShadow(context, value, result); - } -} - -} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h b/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h index f2a03483d83..31f3f587550 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -1052,6 +1053,102 @@ inline void fromRawValue( } } +inline void fromRawValue( + const PropsParserContext& context, + const RawValue& value, + std::vector& result) { + react_native_expect(value.hasType>()); + if (!value.hasType>()) { + result = {}; + return; + } + + std::vector boxShadows{}; + auto rawBoxShadows = static_cast>(value); + for (const auto& rawBoxShadow : rawBoxShadows) { + bool isMap = + rawBoxShadow.hasType>(); + react_native_expect(isMap); + if (!isMap) { + // If any box shadow is malformed then we should not apply any of them + // which is the web behavior. + result = {}; + return; + } + + auto rawBoxShadowMap = + static_cast>(rawBoxShadow); + BoxShadow boxShadow{}; + auto offsetX = rawBoxShadowMap.find("offsetX"); + react_native_expect(offsetX != rawBoxShadowMap.end()); + if (offsetX == rawBoxShadowMap.end()) { + result = {}; + return; + } + react_native_expect(offsetX->second.hasType()); + if (!offsetX->second.hasType()) { + result = {}; + return; + } + boxShadow.offsetX = (Float)offsetX->second; + + auto offsetY = rawBoxShadowMap.find("offsetY"); + react_native_expect(offsetY != rawBoxShadowMap.end()); + if (offsetY == rawBoxShadowMap.end()) { + result = {}; + return; + } + react_native_expect(offsetY->second.hasType()); + if (!offsetY->second.hasType()) { + result = {}; + return; + } + boxShadow.offsetY = (Float)offsetY->second; + + auto blurRadius = rawBoxShadowMap.find("blurRadius"); + if (blurRadius != rawBoxShadowMap.end()) { + react_native_expect(blurRadius->second.hasType()); + if (!blurRadius->second.hasType()) { + result = {}; + return; + } + boxShadow.blurRadius = (Float)blurRadius->second; + } + + auto spreadDistance = rawBoxShadowMap.find("spreadDistance"); + if (spreadDistance != rawBoxShadowMap.end()) { + react_native_expect(spreadDistance->second.hasType()); + if (!spreadDistance->second.hasType()) { + result = {}; + return; + } + boxShadow.spreadDistance = (Float)spreadDistance->second; + } + + auto inset = rawBoxShadowMap.find("inset"); + if (inset != rawBoxShadowMap.end()) { + react_native_expect(inset->second.hasType()); + if (!inset->second.hasType()) { + result = {}; + return; + } + boxShadow.inset = (bool)inset->second; + } + + auto color = rawBoxShadowMap.find("color"); + if (color != rawBoxShadowMap.end()) { + fromRawValue( + context.contextContainer, + context.surfaceId, + color->second, + boxShadow.color); + } + + boxShadows.push_back(boxShadow); + } + + result = boxShadows; +} inline void fromRawValue( const PropsParserContext& context, const RawValue& value,