From c3b86de4d8a0e827453203d85dc13feb67874999 Mon Sep 17 00:00:00 2001 From: Nishan Date: Sun, 1 Sep 2024 13:37:08 +1200 Subject: [PATCH 1/2] fix: platform color android --- .../react/uimanager/style/Gradient.kt | 11 +++++-- .../react/views/view/ReactViewManager.java | 2 +- .../LinearGradient/LinearGradientExample.js | 31 ++++++++++++++++++- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/Gradient.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/Gradient.kt index 14d027924315..3e99ee2f085e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/Gradient.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/Gradient.kt @@ -7,12 +7,15 @@ package com.facebook.react.uimanager.style +import android.content.Context import android.graphics.LinearGradient import android.graphics.Rect import android.graphics.Shader +import com.facebook.react.bridge.ColorPropConverter import com.facebook.react.bridge.ReadableMap +import com.facebook.react.bridge.ReadableType -public class Gradient(gradient: ReadableMap?) { +public class Gradient(gradient: ReadableMap?, context: Context) { private enum class GradientType { LINEAR_GRADIENT } @@ -55,7 +58,11 @@ public class Gradient(gradient: ReadableMap?) { for (i in 0 until size) { val colorStop = colorStops.getMap(i) - colors[i] = colorStop.getInt("color") + if (colorStop.getType("color") == ReadableType.Map) { + colors[i] = ColorPropConverter.getColor(colorStop.getMap("color"), context); + } else { + colors[i] = colorStop.getInt("color"); + } positions[i] = colorStop.getDouble("position").toFloat() } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.java index 546b2d227d0d..f0fdec6b2791 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.java @@ -105,7 +105,7 @@ public void setBackgroundImage(ReactViewGroup view, @Nullable ReadableArray back Gradient[] gradients = new Gradient[backgroundImage.size()]; for (int i = 0; i < backgroundImage.size(); i++) { ReadableMap gradientMap = backgroundImage.getMap(i); - gradients[i] = new Gradient(gradientMap); + gradients[i] = new Gradient(gradientMap, view.getContext()); } view.setGradients(gradients); } else { diff --git a/packages/rn-tester/js/examples/LinearGradient/LinearGradientExample.js b/packages/rn-tester/js/examples/LinearGradient/LinearGradientExample.js index add517122311..6d9bfd857e9d 100644 --- a/packages/rn-tester/js/examples/LinearGradient/LinearGradientExample.js +++ b/packages/rn-tester/js/examples/LinearGradient/LinearGradientExample.js @@ -13,7 +13,7 @@ import type {ViewStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet'; import React from 'react'; -import {StyleSheet, Text, View} from 'react-native'; +import {Platform, PlatformColor, StyleSheet, Text, View} from 'react-native'; type Props = $ReadOnly<{ style: ViewStyleProp, @@ -157,4 +157,33 @@ exports.examples = [ ); }, }, + { + title: 'Gradient with Platform colors', + render(): React.Node { + return ( + + ); + }, + }, ]; From 2343c7d97790d1195c8b70444f61da7a6e9a7930 Mon Sep 17 00:00:00 2001 From: Nishan Date: Sun, 1 Sep 2024 13:49:06 +1200 Subject: [PATCH 2/2] add test cases --- .../__tests__/processBackgroundImage-test.js | 66 ++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/packages/react-native/Libraries/StyleSheet/__tests__/processBackgroundImage-test.js b/packages/react-native/Libraries/StyleSheet/__tests__/processBackgroundImage-test.js index d99d51b7af60..f7898db9c936 100644 --- a/packages/react-native/Libraries/StyleSheet/__tests__/processBackgroundImage-test.js +++ b/packages/react-native/Libraries/StyleSheet/__tests__/processBackgroundImage-test.js @@ -11,7 +11,13 @@ 'use strict'; import processBackgroundImage from '../processBackgroundImage'; - +const {OS} = require('../../Utilities/Platform'); +const PlatformColorAndroid = + require('../PlatformColorValueTypes.android').PlatformColor; +const PlatformColorIOS = + require('../PlatformColorValueTypes.ios').PlatformColor; +const DynamicColorIOS = + require('../PlatformColorValueTypesIOS.ios').DynamicColorIOS; const processColor = require('../processColor').default; describe('processBackgroundImage', () => { @@ -564,4 +570,62 @@ describe('processBackgroundImage', () => { expect(result).toEqual([]); expect(result1).toEqual([]); }); + + describe('iOS', () => { + if (OS === 'ios') { + it('should process iOS PlatformColor colors', () => { + const result = processBackgroundImage([ + { + type: 'linearGradient', + colorStops: [ + {color: PlatformColorIOS('systemRedColor'), positions: ['0%']}, + {color: 'red', positions: ['100%']}, + ], + }, + ]); + expect(result[0].colorStops[0].color).toEqual({ + semantic: ['systemRedColor'], + }); + }); + it('should process iOS Dynamic colors', () => { + const result = processBackgroundImage([ + { + type: 'linearGradient', + colorStops: [ + { + color: DynamicColorIOS({light: 'black', dark: 'white'}), + positions: ['0%'], + }, + {color: 'red', positions: ['100%']}, + ], + }, + ]); + expect(result[0].colorStops[0].color).toEqual({ + dynamic: {light: 0xff000000, dark: 0xffffffff}, + }); + }); + } + }); + + describe('Android', () => { + if (OS === 'android') { + it('should process Android PlatformColor colors', () => { + const result = processBackgroundImage([ + { + type: 'linearGradient', + colorStops: [ + { + color: PlatformColorAndroid('?attr/colorPrimary'), + positions: ['0%'], + }, + {color: 'red', positions: ['100%']}, + ], + }, + ]); + expect(result[0].colorStops[0].color).toEqual({ + resource_paths: ['?attr/colorPrimary'], + }); + }); + } + }); });