Foreground ripple support in Pressable (#31632)

Summary:
This PR aims to enable support for foreground ripple in Pressable. This makes it possible to show ripple on top of custom child components like Image as shown in the below example.

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

[Android] [Added] - Support for foreground ripple in Pressable

Pull Request resolved: https://github.com/facebook/react-native/pull/31632

Test Plan:
- Pass property useForeground: true in android_ripple config to verify the changes.

https://user-images.githubusercontent.com/23293248/120111371-4cecbf00-c18f-11eb-8acb-d10718d5483c.mov

Reviewed By: kacieb

Differential Revision: D28926493

Pulled By: yungsters

fbshipit-source-id: 12a6ba71a7dc6ed60fbaeb651f015cace38e03b1
This commit is contained in:
Nishan Bende 2021-06-07 17:07:00 -07:00 коммит произвёл Facebook GitHub Bot
Родитель 1cc2229380
Коммит 0823f299e5
2 изменённых файлов: 38 добавлений и 14 удалений

Просмотреть файл

@ -27,6 +27,7 @@ export type RippleConfig = {|
color?: ColorValue, color?: ColorValue,
borderless?: boolean, borderless?: boolean,
radius?: number, radius?: number,
foreground?: boolean,
|}; |};
/** /**
@ -40,11 +41,11 @@ export default function useAndroidRippleForView(
onPressIn: (event: PressEvent) => void, onPressIn: (event: PressEvent) => void,
onPressMove: (event: PressEvent) => void, onPressMove: (event: PressEvent) => void,
onPressOut: (event: PressEvent) => void, onPressOut: (event: PressEvent) => void,
viewProps: $ReadOnly<{| viewProps:
nativeBackgroundAndroid: NativeBackgroundProp, | $ReadOnly<{|nativeBackgroundAndroid: NativeBackgroundProp|}>
|}>, | $ReadOnly<{|nativeForegroundAndroid: NativeBackgroundProp|}>,
|}> { |}> {
const {color, borderless, radius} = rippleConfig ?? {}; const {color, borderless, radius, foreground} = rippleConfig ?? {};
return useMemo(() => { return useMemo(() => {
if ( if (
@ -58,16 +59,18 @@ export default function useAndroidRippleForView(
'Unexpected color given for Ripple color', 'Unexpected color given for Ripple color',
); );
return { const nativeRippleValue = {
viewProps: {
// Consider supporting `nativeForegroundAndroid`
nativeBackgroundAndroid: {
type: 'RippleAndroid', type: 'RippleAndroid',
color: processedColor, color: processedColor,
borderless: borderless === true, borderless: borderless === true,
rippleRadius: radius, rippleRadius: radius,
}, };
},
return {
viewProps:
foreground === true
? {nativeForegroundAndroid: nativeRippleValue}
: {nativeBackgroundAndroid: nativeRippleValue},
onPressIn(event: PressEvent): void { onPressIn(event: PressEvent): void {
const view = viewRef.current; const view = viewRef.current;
if (view != null) { if (view != null) {
@ -98,5 +101,5 @@ export default function useAndroidRippleForView(
}; };
} }
return null; return null;
}, [color, borderless, radius, viewRef]); }, [borderless, color, foreground, radius, viewRef]);
} }

Просмотреть файл

@ -11,6 +11,7 @@
import * as React from 'react'; import * as React from 'react';
import { import {
Animated, Animated,
Image,
Pressable, Pressable,
StyleSheet, StyleSheet,
Text, Text,
@ -310,6 +311,10 @@ const styles = StyleSheet.create({
fontWeight: '500', fontWeight: '500',
color: 'blue', color: 'blue',
}, },
image: {
height: 100,
width: 100,
},
}); });
exports.displayName = (undefined: ?string); exports.displayName = (undefined: ?string);
@ -425,6 +430,22 @@ exports.examples = [
</Text> </Text>
</View> </View>
</Pressable> </Pressable>
<View style={{alignItems: 'center'}}>
<Pressable
android_ripple={{
borderless: false,
foreground: true,
}}>
<Image
source={{
uri: 'https://www.facebook.com/ads/pics/successstories.png',
}}
style={styles.image}
/>
</Pressable>
<Text>use foreground</Text>
</View>
</View> </View>
); );
}, },