Skip to content
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

Allow PlatformColor to work with RCTView border colors #29728

Closed

Conversation

danilobuerger
Copy link
Contributor

@danilobuerger danilobuerger commented Aug 22, 2020

Summary

Using PlatformColor with border colors doesn't work currently when switching dark mode as the information is lost when converting to CGColor. This change keeps the border colors around as UIColor so switching to dark mode works.

<View
  style={{
    borderColor: DynamicColorIOS({ dark: "yellow", light: "red" }),
    borderWidth: 1,
  }}
>
...
</View>

This view will start with a red border (assuming light mode when started), but will not change to a yellow border when switching to dark mode. With this PR, the border color will be correctly set to yellow.

Changelog

[iOS] [Fixed] - Allow PlatformColor to work with border colors

Test Plan

  1. Assign a PlatformColor or DynamicColorIOS to a view border color.
  2. Toggle between dark / light mode. See the colors change.

@react-native-bot react-native-bot added Bug Platform: iOS iOS applications. labels Aug 22, 2020
@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Aug 22, 2020
@analysis-bot
Copy link

analysis-bot commented Aug 22, 2020

Platform Engine Arch Size (bytes) Diff
ios - universal n/a --

Base commit: 36b0f7d

@analysis-bot
Copy link

Platform Engine Arch Size (bytes) Diff
android hermes arm64-v8a 7,004,367 0
android hermes armeabi-v7a 6,667,956 0
android hermes x86 7,424,653 0
android hermes x86_64 7,315,568 0
android jsc arm64-v8a 9,164,186 0
android jsc armeabi-v7a 8,819,910 0
android jsc x86 9,012,595 0
android jsc x86_64 9,589,672 0

Base commit: 2d34c22

@rosskhanas
Copy link

Is there a chance to have it in 0.64.0?

@rosskhanas
Copy link

@danilobuerger this PR implements proper border support on iOS, how about the Android support? At the moment border color on Android does not work at all with PlatformColor. Thank you!

@danilobuerger
Copy link
Contributor Author

Hi @shergin 👋 I would love to move this PR forward. Is there anything missing in order to get it merged?

@danilobuerger
Copy link
Contributor Author

The failing circleci test seem to be unrelated:

Wrong version of Flow. The config specifies version ^0.131.0 but this is version 0.132.0
Flow check failed.

@TheSavior
Copy link
Member

Following up on this, does PlatformColor work on Android for border colors? If things are currently consistent (with it not working on either platform) and this PR will diverge the platforms, we aren't likely to merge this. If they already work on Android and this just fixes iOS then this is fine. Otherwise we will need a PR adding support on Android

@kuasha420
Copy link

Following up on this, does PlatformColor work on Android for border colors? If things are currently consistent (with it not working on either platform) and this PR will diverge the platforms, we aren't likely to merge this. If they already work on Android and this just fixes iOS then this is fine. Otherwise we will need a PR adding support on Android

This PR seems to be focused on Applying PlatformColor to borderColor on color scheme switch via DynamicColorIOS which doesn't exist for Android.

However, from my testing, PlatformColor can't be applied to borderColor of a view on Android. This error pops up.

screenshot-2020-10-27_12 51 07 124

@TheSavior
Copy link
Member

On the native side I'd expect any property that can accept PlatformColor would also be able to accept DynamicColorIOS on iOS. So yeah, it sounds like the behavior is currently consistent between iOS and Android and neither of them support using PlatformColor on borders.

For this feature to land, there should be an addition to the RNTester PlatformColor screen that exercises setting border colors, and their should be an implementation for Android, either in this PR or a separate PR.

@kuasha420
Copy link

kuasha420 commented Oct 28, 2020

On the native side I'd expect any property that can accept PlatformColor would also be able to accept DynamicColorIOS on iOS. So yeah, it sounds like the behavior is currently consistent between iOS and Android and neither of them support using PlatformColor on borders.

For this feature to land, there should be an addition to the RNTester PlatformColor screen that exercises setting border colors, and their should be an implementation for Android, either in this PR or a separate PR.

Not quite. Looks like PlatformColor works just fine as borderColor on IOS.

Simulator Screen Shot - iPhone 11 - 2020-10-28 at 06 49 52

import React from 'react';
import { Appearance, Platform, PlatformColor, SafeAreaView, StatusBar, StyleSheet, Text, View } from 'react-native';

const App = () => {
  return (
    <>
      <StatusBar barStyle="dark-content" />
      <SafeAreaView style={styles.container}>
        <View style={styles.borderTest}>
          <Text>Border Color Test</Text>
        </View>
        <View style={styles.information}>
          <Text>Current Color Scheme: {Appearance.getColorScheme()}</Text>
        </View>
      </SafeAreaView>
    </>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  borderTest: {
    borderWidth: 5,
    ...Platform.select({
      ios: {
        borderColor: PlatformColor('systemBlue'),
      },
      android: {
        borderColor: PlatformColor('@android:color/holo_blue_bright'),
      },
      default: {
        borderColor: 'red',
      },
    }),
    alignItems: 'center',
    justifyContent: 'center',
    flex: 1,
  },
  information: {
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default App;

@TheSavior
Copy link
Member

TheSavior commented Oct 28, 2020

I think I'm a little confused at this point 😅, is this recap correct?

Before this diff:
PlatformColor as border color on iOS and Android work as expected.
DynamicColorIOS as border color on iOS does not work as expected.

After this diff:
DynamicColorIOS as border color on iOS works as expected.

Is this correct?

@kuasha420
Copy link

@TheSavior whoops. I think I've confused you more. There's the situation from my testing.

Before the diff

  1. PlatformColor as background or color works on all platform (ios and android)

  2. PlatformColor as border color works on IOS but doesn't work on Android (throws the above error).

  3. DynamicColorIOS works for background & color and applies dynamic change of color scheme on runtime.

  4. DynamicColorIOS works for borderColor but does not apply changes according to color scheme change on runtime.

After the diff

1, 2 & 3 remains unchanged.

  1. Now runtime color scheme change also changes borderColor.

In summery, this PR just fixes dynamicColorIOS to dynamically apply border color on runtime color scheme change. PlatformColor as border color never worked on android anyways.

The Title of the PR is misleading, the description is correct.

@kuasha420
Copy link

kuasha420 commented Oct 28, 2020

PlatformColor as border color on iOS and Android work as expected.

@TheSavior PlatformColor as borderColor works on ios. but crashes on android (In both RN63.3 & master with this diff). I don't think it's expected :)

@guyca
Copy link

guyca commented Oct 28, 2020

@kuasha420 Any Android error you encounter is not related to this PR and was not caused by it. As you've mentioned, this PR addresses a specific bug on iOS. It was never intended to fix all PlatformColor issues.

As no regressions were introduced by this PR, and it does fix the issue described, what's holding us back from merging it and benefiting from it? 💪

@kuasha420
Copy link

kuasha420 commented Oct 28, 2020

@guyca Other than the confusing title that tripped off @TheSavior the PR is Good to go imho. The title should be fix: allow DynamicColorIOS to dynamically apply correct borderColor on Color Scheme change.

@TheSavior
Copy link
Member

Alright, this extra context makes sense. Thanks for breaking it down for me. I've updated the title.

I'm not familiar with the native code backing the colors, but I'm kinda surprised that the native code to support PlatformColor doesn't automatically work for DynamicColorIOS. That seems ripe for other potential issues down the road. cc @tom-un, does this PR look good to you?

This PR should also update the RNTester screen for Colors to exercise this use case in order to make sure we don't cause regressions here in the future. It would be an update to this file: https://github.com/facebook/react-native/blob/master/packages/rn-tester/js/examples/PlatformColor/PlatformColorExample.js

@TheSavior TheSavior changed the title Allow PlatformColor to work with RCTView border colors fix: allow DynamicColorIOS to dynamically apply correct borderColor on Color Scheme change Oct 28, 2020
@danilobuerger
Copy link
Contributor Author

danilobuerger commented Oct 28, 2020

@kuasha420 thanks for looking into it. However, your assessment of PlatformColor is incorrect. When applying a PlatformColor and then changing the appearance, the applied border color will not change. But they should as iOS system colors have different appearances (https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/color/#dynamic-system-colors).

@TheSavior the title was correct. This also fixes a bug with PlatformColor.

This changes border colors to use UIColor instead of CGColor.
Only then can dark mode switch to the appropriate color.
@danilobuerger
Copy link
Contributor Author

@TheSavior I updated the DynamicColorIOS example in the linked RNTester Screen.

@TheSavior TheSavior changed the title fix: allow DynamicColorIOS to dynamically apply correct borderColor on Color Scheme change Allow PlatformColor to work with RCTView border colors Oct 28, 2020
@birkir
Copy link
Contributor

birkir commented May 29, 2021

The tests that are failing seem unrelated to this PR.

Any chance of getting this PR merged, allowing for cherry pick into 0.64.2 ?

@danilobuerger
Copy link
Contributor Author

Hi @p-sun since you recently merged another PlatformColor PR, do you mind giving this one some attention? I have been waiting for a review since August 2020 now.

@facebook-github-bot
Copy link
Contributor

@p-sun has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@p-sun merged this pull request in c974cbf.

@facebook-github-bot facebook-github-bot added the Merged This PR has been merged. label Jun 23, 2021
@danilobuerger danilobuerger deleted the platform-border-color branch June 23, 2021 20:48
grabbou pushed a commit that referenced this pull request Jul 16, 2021
Summary:
# See PR
#29728

# From PR Author
Using `PlatformColor` with border colors doesn't work currently when switching dark mode as the information is lost when converting to `CGColor`. This change keeps the border colors around as `UIColor` so switching to dark mode works.

```ts
<View
  style={{
    borderColor: DynamicColorIOS({ dark: "yellow", light: "red" }),
    borderWidth: 1,
  }}
>
...
</View>
```
This view will start with a red border (assuming light mode when started), but will not change to a yellow border when switching to dark mode. With this PR, the border color will be correctly set to yellow.

## Changelog

[iOS] [Fixed] - Allow PlatformColor to work with border colors

Pull Request resolved: #29728

Test Plan:
1. Assign a `PlatformColor` or `DynamicColorIOS` to a view border color.
2. Toggle between dark / light mode. See the colors change.

Reviewed By: lunaleaps

Differential Revision: D29268376

Pulled By: p-sun

fbshipit-source-id: 586545b05be0beb0e6e5ace6e3f74b304620ad94
@a-eid
Copy link

a-eid commented Jan 21, 2022

@danilobuerger any chance to support android as well #32942

facebook-github-bot pushed a commit that referenced this pull request Feb 7, 2022
Summary:
c974cbf changed the border colors to be of UIColor instead of CGColor. This allowed working with dark mode to switch the border colors automatically. However, in certain situation the system can't resolve the current trait collection (see https://stackoverflow.com/a/57177411/2525941). This commit resolves the colors with the current trait collection to ensure the right colors are selected. This matches with the behavior of how the background color is resolved (also in displayLayer:).

## Changelog

[iOS] [Fixed] - Resolve border platform color based on current trait collection

Pull Request resolved: #32492

Test Plan: Same test plan as #29728

Reviewed By: sammy-SC

Differential Revision: D33819225

Pulled By: cortinico

fbshipit-source-id: 2f8024be7ee7b32d1852373b47fa1437cc569391
facebook-github-bot pushed a commit that referenced this pull request Feb 25, 2022
Summary:
In c974cbf I changed the borderColor from CGColor to UIColor. I missed this view property which should also be updated to reflect the original change.

## Changelog

[iOS] [Fixed] - Set RCTView borderColor to UIColor

Pull Request resolved: #33176

Test Plan: Nothing to test. See PR #29728

Reviewed By: javache

Differential Revision: D34461141

Pulled By: genkikondo

fbshipit-source-id: 51adf39c1cebe8e3b53285961358e4c7f26192db
Saadnajmi pushed a commit to Saadnajmi/react-native-macos that referenced this pull request Jan 15, 2023
Summary:
In facebook@c974cbf I changed the borderColor from CGColor to UIColor. I missed this view property which should also be updated to reflect the original change.

## Changelog

[iOS] [Fixed] - Set RCTView borderColor to UIColor

Pull Request resolved: facebook#33176

Test Plan: Nothing to test. See PR facebook#29728

Reviewed By: javache

Differential Revision: D34461141

Pulled By: genkikondo

fbshipit-source-id: 51adf39c1cebe8e3b53285961358e4c7f26192db
shwanton pushed a commit to shwanton/react-native-macos that referenced this pull request Feb 13, 2023
Summary:
facebook@c974cbf changed the border colors to be of UIColor instead of CGColor. This allowed working with dark mode to switch the border colors automatically. However, in certain situation the system can't resolve the current trait collection (see https://stackoverflow.com/a/57177411/2525941). This commit resolves the colors with the current trait collection to ensure the right colors are selected. This matches with the behavior of how the background color is resolved (also in displayLayer:).

## Changelog

[iOS] [Fixed] - Resolve border platform color based on current trait collection

Pull Request resolved: facebook#32492

Test Plan: Same test plan as facebook#29728

Reviewed By: sammy-SC

Differential Revision: D33819225

Pulled By: cortinico

fbshipit-source-id: 2f8024be7ee7b32d1852373b47fa1437cc569391
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged This PR has been merged. Needs: React Native Team Attention Platform: iOS iOS applications.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants