-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support PlatformColor #1561
Support PlatformColor #1561
Conversation
src/index.d.ts
Outdated
@@ -1,6 +1,6 @@ | |||
import * as React from 'react'; | |||
import * as ReactNative from 'react-native'; | |||
import { GestureResponderEvent } from 'react-native'; | |||
import { GestureResponderEvent, OpaqueColorValue } from 'react-native'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this just be "ColorValue"?
@@ -101,7 +101,7 @@ export type rgbaArray = ReadonlyArray<number>; | |||
// int32ARGBColor = 0xaarrggbb | |||
export type int32ARGBColor = number; | |||
|
|||
export type Color = int32ARGBColor | rgbaArray | string; | |||
export type Color = int32ARGBColor | rgbaArray | OpaqueColorValue | string; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we just replace the "Color" type altogether with "ColorValue" from react native? It should represent the same set of types of colors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not the same, from the type it's string | OpaqueColorValue
so we could replace the string
with this one, but not the whole type. I prefer to use OpaqueColorValue
here as I'm not sure what types will be added to ColorValue
in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was under the impression that ColorValue
is just the standard Color type in React Native 0.63+, and that OpaqueColorValue
will include all the extra types of colors that can be passed to native. In react-native-macos (which we recently added support for in react-native-svg), I extended ColorValue/OpaqueColorValue to include a new API ColorWithSystemEffectMacOS
(microsoft/react-native-macos#751).
But also, I thought the idea of OpaqueColorValue
is that we do not need to know the specifics of the type, as long as it gets passed over the bridge to RCTConvert UIColor:]
(or whatever the equivalent on Android is), React Native will make sure it's a valid native color. Is there a reason we need to know the specifics of the types of colors now? I was under the impression we could abstract most of that away to React Native and would need less processing on this repo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can find the definition here:
export type ColorValue = string | OpaqueColorValue;
So it's not the same, and it can't be replaced as the way this library deals with colors is quite custom. I'm not the author of this library, but i guess it's partly due to color inheritance. If it was not dealing with colors in a custom way then this PR wouldn't be necessary.
// iOS PlatformColor | ||
if ('semantic' in color) { | ||
return [0, color]; | ||
} | ||
|
||
// Android PlatformColor | ||
if ('resource_paths' in color) { | ||
return [0, color]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At least on iOS, "semantic" isn't enough, because a color might be a DynamicColor instead. Could we instead do something like a type check? if (typeof color === ColorValue) ....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DynamicColorIOS
isn't supported in this PR, and I don't really see that API surviving long term as it's iOS only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Surviving in react-native, or surviving in this repo? I don't think it's going anywhere as long as PlatformColor exists. We also have a react-native-macos equivalent DynacmicColorMacOS
that won't go anywhere as long as DynamicColor exists.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant in react-native
. DynamicColorIOS
predates PlaformColor
, and while it's not able to fully replace it just yet, I don't see that API as useful without cross platform support. I guess is possible to add however.
@Saadnajmi How can we make this PR progress? |
@oblador @Saadnajmi @brentvatne @msand |
Any update to support PlatformColor? |
@oblador I've installed your PR branch through npm, but it doesn't compile with Babel: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left some suggestions regarding the code, which we can fix in a follow-up PR. Other from that, it looks like it's ready to be merged 🎉
@@ -13,48 +13,49 @@ | |||
|
|||
@implementation RNSVGSolidColorBrush | |||
{ | |||
CGColorRef _color; | |||
UIColor *_color; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we should use RNSVGColor
so it compiles on macOS
.
return CGColorCreateCopyWithAlpha(_color, opacity * CGColorGetAlpha(_color)); | ||
CGColorRef baseColor = _color.CGColor; | ||
CGColorRef color = CGColorCreateCopyWithAlpha(baseColor, opacity * CGColorGetAlpha(baseColor)); | ||
CGColorRelease(baseColor); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not release it since it will release CGColor
prop of _color
, so trying to use _color.CGColor
again will lead to crash.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure about that? Why would releasing _baseColor affect _color?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, now I see, good catch 👍
@@ -40,6 +40,16 @@ export default function extractBrush(color?: Color) { | |||
return int32ARGBColor; | |||
} | |||
|
|||
// iOS PlatformColor | |||
if ('semantic' in color) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think here we should also add a check for if color
is an object, as suggested here by @gaodeng : https://github.com/oblador/react-native-svg/pull/1/files#diff-955398674a5278517eeeb9b5daca466f8e891b408d79757c3afbfa58a552a324R78
One more thing about |
Summary
Since version 0.63 React Native has supported
PlatformColor
structs that among other features has dark mode support built in. Using those values with RNSVG today throws a warning"[Object object]" is not a valid color or brush
and makes the path have a clear color.This PR adds support for
PlatformColor
by utilizing the color parsing code shipped with React Native itself. In order to support the dynamic properties I had to retain the reference as aUIColor
and convert it toCGColorRef
as it's read. This might have a performance penalty.The Android implementation doesn't yet have support for dynamic values (EDIT: react-native itself doesn't support it, so we're good there I think). Since it relies on the
ColorPropConverter
class, I think it means minimum supported version of RN will be raised to 0.63.Fixes #1391
Test Plan
I couldn't find an example project in the repo, so I used my own example project, see video:
Compatibility
Checklist
README.md
__tests__
folder