diff --git a/ReactCommon/react/renderer/graphics/React-graphics.podspec b/ReactCommon/react/renderer/graphics/React-graphics.podspec index e67f8f506a4..74729d28ec5 100644 --- a/ReactCommon/react/renderer/graphics/React-graphics.podspec +++ b/ReactCommon/react/renderer/graphics/React-graphics.podspec @@ -39,4 +39,5 @@ Pod::Spec.new do |s| s.pod_target_xcconfig = { "USE_HEADERMAP" => "NO", "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_TARGET_SRCROOT)/../../../\" \"$(PODS_ROOT)/RCT-Folly\"" } s.dependency "RCT-Folly/Fabric", folly_version + s.dependency "React-Core/Default", version end diff --git a/ReactCommon/react/renderer/graphics/platform/ios/RCTPlatformColorUtils.h b/ReactCommon/react/renderer/graphics/platform/ios/RCTPlatformColorUtils.h new file mode 100644 index 00000000000..6994c1e0b85 --- /dev/null +++ b/ReactCommon/react/renderer/graphics/platform/ios/RCTPlatformColorUtils.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include + +facebook::react::ColorComponents RCTPlatformColorComponentsFromSemanticItems( + std::vector &semanticItems); diff --git a/ReactCommon/react/renderer/graphics/platform/ios/RCTPlatformColorUtils.mm b/ReactCommon/react/renderer/graphics/platform/ios/RCTPlatformColorUtils.mm new file mode 100644 index 00000000000..baa232423a8 --- /dev/null +++ b/ReactCommon/react/renderer/graphics/platform/ios/RCTPlatformColorUtils.mm @@ -0,0 +1,206 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import "RCTPlatformColorUtils.h" + +#import +#import +#import + +#include + +NS_ASSUME_NONNULL_BEGIN + +static NSString *const kColorSuffix = @"Color"; +static NSString *const kFallbackARGBKey = @"fallback-argb"; + +static NSDictionary *_PlatformColorSelectorsDict() +{ + static NSDictionary *dict; + static dispatch_once_t once_token; + dispatch_once(&once_token, ^(void) { + dict = @{ + // https://developer.apple.com/documentation/uikit/uicolor/ui_element_colors + // Label Colors + @"label" : @{ + kFallbackARGBKey : @(0xFF000000) // iOS 13.0 + }, + @"secondaryLabel" : @{ + kFallbackARGBKey : @(0x993c3c43) // iOS 13.0 + }, + @"tertiaryLabel" : @{ + kFallbackARGBKey : @(0x4c3c3c43) // iOS 13.0 + }, + @"quaternaryLabel" : @{ + kFallbackARGBKey : @(0x2d3c3c43) // iOS 13.0 + }, + // Fill Colors + @"systemFill" : @{ + kFallbackARGBKey : @(0x33787880) // iOS 13.0 + }, + @"secondarySystemFill" : @{ + kFallbackARGBKey : @(0x28787880) // iOS 13.0 + }, + @"tertiarySystemFill" : @{ + kFallbackARGBKey : @(0x1e767680) // iOS 13.0 + }, + @"quaternarySystemFill" : @{ + kFallbackARGBKey : @(0x14747480) // iOS 13.0 + }, + // Text Colors + @"placeholderText" : @{ + kFallbackARGBKey : @(0x4c3c3c43) // iOS 13.0 + }, + // Standard Content Background Colors + @"systemBackground" : @{ + kFallbackARGBKey : @(0xFFffffff) // iOS 13.0 + }, + @"secondarySystemBackground" : @{ + kFallbackARGBKey : @(0xFFf2f2f7) // iOS 13.0 + }, + @"tertiarySystemBackground" : @{ + kFallbackARGBKey : @(0xFFffffff) // iOS 13.0 + }, + // Grouped Content Background Colors + @"systemGroupedBackground" : @{ + kFallbackARGBKey : @(0xFFf2f2f7) // iOS 13.0 + }, + @"secondarySystemGroupedBackground" : @{ + kFallbackARGBKey : @(0xFFffffff) // iOS 13.0 + }, + @"tertiarySystemGroupedBackground" : @{ + kFallbackARGBKey : @(0xFFf2f2f7) // iOS 13.0 + }, + // Separator Colors + @"separator" : @{ + kFallbackARGBKey : @(0x493c3c43) // iOS 13.0 + }, + @"opaqueSeparator" : @{ + kFallbackARGBKey : @(0xFFc6c6c8) // iOS 13.0 + }, + // Link Color + @"link" : @{ + kFallbackARGBKey : @(0xFF007aff) // iOS 13.0 + }, + // Nonadaptable Colors + @"darkText" : @{}, + @"lightText" : @{}, + // https://developer.apple.com/documentation/uikit/uicolor/standard_colors + // Adaptable Colors + @"systemBlue" : @{}, + @"systemBrown" : @{ + kFallbackARGBKey : @(0xFFa2845e) // iOS 13.0 + }, + @"systemGreen" : @{}, + @"systemIndigo" : @{ + kFallbackARGBKey : @(0xFF5856d6) // iOS 13.0 + }, + @"systemOrange" : @{}, + @"systemPink" : @{}, + @"systemPurple" : @{}, + @"systemRed" : @{}, + @"systemTeal" : @{}, + @"systemYellow" : @{}, + // Adaptable Gray Colors + @"systemGray" : @{}, + @"systemGray2" : @{ + kFallbackARGBKey : @(0xFFaeaeb2) // iOS 13.0 + }, + @"systemGray3" : @{ + kFallbackARGBKey : @(0xFFc7c7cc) // iOS 13.0 + }, + @"systemGray4" : @{ + kFallbackARGBKey : @(0xFFd1d1d6) // iOS 13.0 + }, + @"systemGray5" : @{ + kFallbackARGBKey : @(0xFFe5e5ea) // iOS 13.0 + }, + @"systemGray6" : @{ + kFallbackARGBKey : @(0xFFf2f2f7) // iOS 13.0 + }, + // Transparent Color + @"clear" : @{ + kFallbackARGBKey : @(0x00000000) // iOS 13.0 + }, + }; + }); + return dict; +} + +static UIColor *_UIColorFromHexValue(NSNumber *hexValue) +{ + NSUInteger hexIntValue = [hexValue unsignedIntegerValue]; + + CGFloat red = ((CGFloat)((hexIntValue & 0xFF000000) >> 24)) / 255.0; + CGFloat green = ((CGFloat)((hexIntValue & 0xFF0000) >> 16)) / 255.0; + CGFloat blue = ((CGFloat)((hexIntValue & 0xFF00) >> 8)) / 255.0; + CGFloat alpha = ((CGFloat)(hexIntValue & 0xFF)) / 255.0; + + return [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; +} + +static UIColor *_Nullable _UIColorFromSemanticString(NSString *semanticString) +{ + NSString *platformColorString = [semanticString hasSuffix:kColorSuffix] + ? [semanticString substringToIndex:[semanticString length] - [kColorSuffix length]] + : semanticString; + NSDictionary *platformColorSelectorsDict = _PlatformColorSelectorsDict(); + NSDictionary *colorInfo = platformColorSelectorsDict[platformColorString]; + if (colorInfo) { + SEL objcColorSelector = NSSelectorFromString([platformColorString stringByAppendingString:kColorSuffix]); + if (![UIColor respondsToSelector:objcColorSelector]) { + NSNumber *fallbackRGB = colorInfo[kFallbackARGBKey]; + if (fallbackRGB) { + return _UIColorFromHexValue(fallbackRGB); + } + } else { + Class uiColorClass = [UIColor class]; + IMP imp = [uiColorClass methodForSelector:objcColorSelector]; + id (*getUIColor)(id, SEL) = ((id(*)(id, SEL))imp); + id colorObject = getUIColor(uiColorClass, objcColorSelector); + if ([colorObject isKindOfClass:[UIColor class]]) { + return colorObject; + } + } + } + return nil; +} + +static inline NSString *_NSStringFromCString( + const std::string &string, + const NSStringEncoding &encoding = NSUTF8StringEncoding) +{ + return [NSString stringWithCString:string.c_str() encoding:encoding]; +} + +static inline facebook::react::ColorComponents _ColorComponentsFromUIColor(UIColor *color) +{ + CGFloat rgba[4]; + RCTGetRGBAColorComponents(color.CGColor, rgba); + return {(float)rgba[0], (float)rgba[1], (float)rgba[2], (float)rgba[3]}; +} + +facebook::react::ColorComponents RCTPlatformColorComponentsFromSemanticItems(std::vector &semanticItems) +{ + for (const auto &semanticCString : semanticItems) { + if (@available(iOS 11.0, *)) { + NSString *semanticNSString = _NSStringFromCString(semanticCString); + UIColor *uiColor = [UIColor colorNamed:semanticNSString]; + if (uiColor != nil) { + return _ColorComponentsFromUIColor(uiColor); + } + uiColor = _UIColorFromSemanticString(semanticNSString); + if (uiColor != nil) { + return _ColorComponentsFromUIColor(uiColor); + } + } + } + + return {0, 0, 0, 0}; +} + +NS_ASSUME_NONNULL_END diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index dc5ff2430fb..3f2bd828528 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -583,6 +583,7 @@ PODS: - ReactCommon/turbomodule/core (= 1000.0.0) - React-graphics (1000.0.0): - RCT-Folly/Fabric (= 2021.06.28.00) + - React-Core/Default (= 1000.0.0) - React-jsi (1000.0.0): - boost (= 1.76.0) - DoubleConversion @@ -879,7 +880,7 @@ SPEC CHECKSUMS: React-CoreModules: 5ee1ed4f8b7f8bdbd45ed155a15c601dca9c73dd React-cxxreact: 20a63475c83c5450442c754305738c6db6070214 React-Fabric: 7641eab239c5fc5669ef22ea08cf383f9066fdcb - React-graphics: 3ea907482e46997c9a14c60521918985f9425504 + React-graphics: db797c4609216593a1a12d1661716898d303900f React-jsi: 7cc3d3691803478047e7d2c8eb5d4c2f9c6d2922 React-jsiexecutor: 02ed9d4a28a8acf44788b4697e13c4aadc42cf72 React-jsinspector: 7d223826b0e7a61b3540c21b9eca2603b1d4e823