feat(Pressable): add support for PlatformColor and alpha#56395
feat(Pressable): add support for PlatformColor and alpha#56395adrcotfas wants to merge 1 commit into
Conversation
|
Hi @adrcotfas! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks! |
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
a6fdea3 to
9b4bdac
Compare
9b4bdac to
5cf9894
Compare
|
@fabriziocucci has imported this pull request. If you are a Meta employee, you can view this in D105819708. |
|
@fabriziocucci merged this pull request in 60d8b28. |
|
This pull request was successfully merged by @adrcotfas in 60d8b28 When will my fix make it into a release? | How to file a pick request? |
Summary: `android_ripple` on `Pressable` (and `TouchableNativeFeedback.Ripple()`) only accepted numeric (pre-processed ARGB int) colors. Passing a `PlatformColor` would throw an invariant in JS, making theme-aware ripple colors impossible. This PR removes those guards and wires up the full color pipeline: 1. **JS** (`useAndroidRippleForView.js`, `TouchableNativeFeedback.js`): removed the `invariant` that rejected non-numeric processed colors. `TouchableNativeFeedback.Ripple()` now accepts `ColorValue` instead of `string`. 2. **C++** (`NativeDrawable.h`, `HostPlatformViewProps.cpp`): `color` changed from `int32_t` to `SharedColor` + a separate `colorResourcePaths` field for `PlatformColor` resource paths. The `fromRawValue` pipeline now resolves both plain colors and `PlatformColor` objects. 3. **Kotlin** (`ReactDrawableHelper.kt`): `getColor()` now handles both numeric and `PlatformColor` map values via `ColorPropConverter.getColor()`, catching `JSApplicationCausedNativeException` to fall back gracefully instead of crashing. 4. **Theme change support** (`ReactViewGroup.kt`): the raw drawable description maps are retained on the view, and `onConfigurationChanged` re-applies them so ripple colors update automatically on light/dark mode switch. A new `alpha: number` (0–1) field is also added so users can apply opacity to a `PlatformColor` whose value is fully opaque and can't have alpha embedded at the JS level. It is applied by multiplying into the resolved color's alpha channel. Unresolvable `PlatformColor` resources are handled gracefully: on New Arch, C++ omits the `color` key so Kotlin falls back to `colorControlHighlight`; on Old Arch, `ReactDrawableHelper` catches the `JSApplicationCausedNativeException` and falls back to `colorControlHighlight` instead of crashing. [ANDROID] [ADDED] - `android_ripple` now accepts `PlatformColor` for theme-aware ripple colors, and a new `alpha` (0–1) parameter for controlling ripple opacity independently of the color value. Pull Request resolved: #56395 Test Plan: **Automated:** - Existing Pressable snapshot tests pass unchanged. - Updated snapshot for `PlatformColor + alpha` to use `?attr/colorAccent` (matching the RNTester example). - Added snapshot test `should not crash with an unresolvable PlatformColor` verifying the component renders at the JS level without throwing. **Manual (RNTester → Pressable → "Pressable with PlatformColor ripple and alpha"):** 1. `PlatformColor('?attr/colorAccent'), no alpha` → full-opacity accent ripple 2. `PlatformColor('?attr/colorAccent'), alpha=0.3` → 30% opacity accent ripple 3. `#FF0000, no alpha` → full red ripple (regression check) 4. `#FF0000, alpha=0.5` → 50% opacity red ripple 5. Toggle system light/dark mode → ripple color updates automatically 6. Pass an intentionally invalid attribute (e.g. `?attr/doesNotExist`) → no crash, ripple falls back to default `colorControlHighlight` grey [Screen_recording_20260410_091000.webm](https://github.com/user-attachments/assets/5607d267-8cf1-4bbe-bad1-a80aac82d027) > [!NOTE] This is required in [React Native Paper](https://github.com/callstack/react-native-paper) to be able to fully support the Material Design specs but also useful as a general purpose feature for providing more flexibility when customizing ripple color. Reviewed By: javache Differential Revision: D105819708 Pulled By: fabriziocucci fbshipit-source-id: d27c43e0b4e619b6af1c8de0cdb2882db05ee33c
|
This pull request was successfully merged by @adrcotfas in 6c6511c When will my fix make it into a release? | How to file a pick request? |
Summary:
android_rippleonPressable(andTouchableNativeFeedback.Ripple()) onlyaccepted numeric (pre-processed ARGB int) colors. Passing a
PlatformColorwould throw an invariant in JS, making theme-aware ripple colors impossible.
This PR removes those guards and wires up the full color pipeline:
useAndroidRippleForView.js,TouchableNativeFeedback.js):removed the
invariantthat rejected non-numeric processed colors.TouchableNativeFeedback.Ripple()now acceptsColorValueinstead ofstring.NativeDrawable.h,HostPlatformViewProps.cpp):colorchanged from
int32_ttoSharedColor+ a separatecolorResourcePathsfield for
PlatformColorresource paths. ThefromRawValuepipeline nowresolves both plain colors and
PlatformColorobjects.ReactDrawableHelper.kt):getColor()now handles bothnumeric and
PlatformColormap values viaColorPropConverter.getColor(),catching
JSApplicationCausedNativeExceptionto fall back gracefullyinstead of crashing.
ReactViewGroup.kt): the raw drawabledescription maps are retained on the view, and
onConfigurationChangedre-applies them so ripple colors update automatically on light/dark mode
switch.
A new
alpha: number(0–1) field is also added so users can apply opacity toa
PlatformColorwhose value is fully opaque and can't have alpha embedded atthe JS level. It is applied by multiplying into the resolved color's alpha
channel.
Unresolvable
PlatformColorresources are handled gracefully: on New Arch,C++ omits the
colorkey so Kotlin falls back tocolorControlHighlight; onOld Arch,
ReactDrawableHelpercatches theJSApplicationCausedNativeExceptionand falls back to
colorControlHighlightinstead of crashing.Changelog:
[ANDROID] [ADDED] -
android_ripplenow acceptsPlatformColorfortheme-aware ripple colors, and a new
alpha(0–1) parameter for controllingripple opacity independently of the color value.
Test Plan:
Automated:
PlatformColor + alphato use?attr/colorAccent(matching the RNTester example).
should not crash with an unresolvable PlatformColorverifying the component renders at the JS level without throwing.
Manual (RNTester → Pressable → "Pressable with PlatformColor ripple and alpha"):
PlatformColor('?attr/colorAccent'), no alpha→ full-opacity accent ripplePlatformColor('?attr/colorAccent'), alpha=0.3→ 30% opacity accent ripple#FF0000, no alpha→ full red ripple (regression check)#FF0000, alpha=0.5→ 50% opacity red ripple?attr/doesNotExist) → nocrash, ripple falls back to default
colorControlHighlightgreyScreen_recording_20260410_091000.webm
Note
This is required in React Native Paper to be able to fully support the Material Design specs but also useful as a general purpose feature for providing more flexibility when customizing ripple color.