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

PlatformColor API #1813

Merged
merged 9 commits into from
Apr 14, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/colors.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@ React Native supports also colors as an `int` values (in RGB color mode):

> **_Note:_** This might appear similar to the Android [Color](https://developer.android.com/reference/android/graphics/Color) ints representation but on Android values are stored in SRGB color mode (0xaarrggbb).

## DynamicColorIOS
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could probably use some examples similar to what you have for PlatformColor

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll sync with tom to try and get an example piece in.


```jsx
static DynamicColorIOS({light: [Object object], dark: [Object object]}): [Object object]
```

The `DynamicColorIOS` function is a platform color type specific to iOS. `DynamicColorIOS` takes a single argument as an object with two keys: light and dark. The values of light and dark themselves must be values returned by the `PlatformColor` function.
kikisaints marked this conversation as resolved.
Show resolved Hide resolved

At runtime, the system will chose which of the two colors to display depending on the current system appearance settings. Dynamic colors are useful for branding colors or other app specific colors that still respond automatically to system setting changes.

The `DynamicColorIOS` function is similar to the iOS native methods [`UIColor colorWithDynamicProvider:`](https://developer.apple.com/documentation/uikit/uicolor/3238040-colorwithdynamicprovider)

## Named colors

In React Native you can also use color name strings as values.
Expand Down
48 changes: 48 additions & 0 deletions docs/platformcolor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
id: platformcolor
title: PlatformColor
---

```
PlatformColor(string)
Copy link

@tom-un tom-un Apr 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see in other API references that Flow notation is being used. The full Flow notation for PlatformColor is: PlatformColor(...names: Array): [Object object]

The PlatformColor function takes an array of strings. The array must have at least one value. At runtime, if the first string value does not resolve to a usable color, then the next string value is used and so on. If none of the values resolve to a color then a RedBox error is raised. This is useful if an app wishes to use a new platform color that is available in later OS releases but not available in earlier OS releases: the latest platform color name may be specified first in the array with fallback color names specified after.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I re-read this, I think it makes more sense to say in English: 'The PlatformColor function takes one or more string value arguments'. The way I wrote it above implies one passes an array literal, but one does not. The Flow notation is somewhat confusing. Also, it looks like I didn't properly markdown escape things. It should be: PlatformColor(...names: Array<string>): [Object object].

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we don't use Flow notation across the board. It's an artifact from when the docs were auto generated. Now when writing new docs we favor more expository snippets ala MDN. For instance:

PlatformColor(color)

PlatformColor(color1, [color2...])

Then:

"The PlatformColor function takes one or more string value arguments, a full list of which can be found below in the color reference. At runtime, if the first string value does not resolve to a usable color, then the next string value is used and so on. If none of the values resolve to a color then a RedBox error is raised."

It's something we're still working on standardizing and are open to suggestions on. But I'm pretty sure PlatformColor(...names: Array<string>): [Object object] would be hard to read for at least 7% of our audience who has no experience with typed notation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is useful to show the return type of the function. It should be completely opaque, all that matters is that it is a value that can be used as a color, anywhere a color can be used.

For reference, func.call uses this syntax: func.call([thisArg[, arg1, arg2, ...argN]]) which for us would be PlatformColor(color1, [color2, ...colorN])

```

Use the `PlatformColor` function to access native colors on the target platform via supplying the native color’s corresponding string value. You pass a string to the `PlatformColor` function, and provided it exists on that platform, that native color will be applied to the control or Javascript component specified in your style. All native color logic also translates if applicable, meaning if the native color specified is themes and/or high contrast sensitive, that logic will also transfer to the JavaScript component being colored.

For a full list of the types of system colors supported, see:

- [Android R.attr](https://developer.android.com/reference/android/R.attr)
- [iOS Color](https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/color/)

## Example

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

export default function App() {
return (
<View>
<Text style={styles.labelCell}>
I am a special label color!
</Text>
</View>
);
}

const styles = StyleSheet.create({
labelCell: {
flex: 1,
alignItems: 'stretch',
...Platform.select({
ios: {color: PlatformColor('labelColor')},
android: {color: PlatformColor('?attr/colorControlNormal')},
default: {color: 'black'},
}),
},
});
```

The string value provided to the `PlatformColor` function must match and agree with the same string as it exists on the native platform the app is being run on. This means to avoid runtime errors the function should be wrapped in a platform check, either through a `Platform.OS === 'platform'` or a `Platform.Select()`.

You can find a complete example that demonstrates proper, intended use of PlatformColor in [PlatformColorExample.js](https://github.com/facebook/react-native/blob/master/RNTester/js/examples/PlatformColor/PlatformColorExample.js).
3 changes: 3 additions & 0 deletions website/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,9 @@
"platform-specific-code": {
"title": "Platform Specific Code"
},
"platformcolor": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should be consistent between PlatformColor and DynamicColorIOS. They are both public APIs from React Native, and they can both be used everywhere any other color can. So if one has a standalone page, they should both have a standalone page. If one is in the colors.md file, they both should be.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused. I got the impression Rachel wanted dynamiccolorios in the colors.md and the platformcolor separate.

@rachelnabors - Should I pull out the dynamiccolorios and put it in APIs as a separate section, or combine both into colors.md?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious what Rachel will say here, but I'm not sure why DynamicColorIOS would be treated differently than PlatformColor since they are the essentially the same.

"title": "PlatformColor"
},
"profiling": {
"title": "Profiling"
},
Expand Down
1 change: 1 addition & 0 deletions website/sidebars.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
"linking",
"panresponder",
"pixelratio",
"platformcolor",
"share",
"stylesheet",
"systrace",
Expand Down