introduce RCTPlatformColorUtils

Summary:
Changelog: [Internal]

in this diff, we add the logic to handle converting PlatformColor strings to their corresponding RGBA values, using `UIColor`'s API as the source of truth of these colors.

functionality not covered yet:
- customColor
- iOS Dynamic Colors
- Variant Colors

Reviewed By: sammy-SC

Differential Revision: D30103451

fbshipit-source-id: 7d7be0f08dc2fb95b606b8f5d73784766787a574
This commit is contained in:
Phillip Pan authored and Facebook GitHub Bot committed 2021-08-10 11:30:58 -07:00
1 parent d583c2f154
commit df65dbb37f
4 files changed
+221 -1

No files matched your search

@@ -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
@@ -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 <react/renderer/graphics/ColorComponents.h>
#include <vector>
facebook::react::ColorComponents RCTPlatformColorComponentsFromSemanticItems(
std::vector<std::string> &semanticItems);
@@ -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 <Foundation/Foundation.h>
#import <React/RCTUtils.h>
#import <UIKit/UIKit.h>
#include <string>
NS_ASSUME_NONNULL_BEGIN
static NSString *const kColorSuffix = @"Color";
static NSString *const kFallbackARGBKey = @"fallback-argb";
static NSDictionary<NSString *, NSDictionary *> *_PlatformColorSelectorsDict()
{
static NSDictionary<NSString *, 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<NSString *, NSDictionary *> *platformColorSelectorsDict = _PlatformColorSelectorsDict();
NSDictionary<NSString *, id> *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<std::string> &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
+2 -1
View File
@@ -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