Files
react-native/Libraries/Components/Pressable/useAndroidRippleForView.js
T
Vojtech Novak 44ec762e41 fix: ripple should be applied even when borderless == false (#28526)
Summary:
With current master, when you render `<Pressable android_ripple={{borderless: false}}>`, there is no ripple effect at all.

I think the expected behavior is to have ripple with default color and radius, just not borderless.

This was how it was done (by me) in https://github.com/facebook/react-native/pull/28156/files but in the import process, the implementation was changed: https://github.com/facebook/react-native/commit/bd3868643d29e93610e19312571a9736df2cbdf8 so either this PR is a fix or you can just close it (but I'd be curious why).

## 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] [fixed] - ripple should be applied even when borderless == false
Pull Request resolved: https://github.com/facebook/react-native/pull/28526

Test Plan:
`<Pressable android_ripple={{borderless: false}}>` on master

![SVID_20200404_123614_1](https://user-images.githubusercontent.com/1566403/78424971-6b315a80-7671-11ea-8be4-5fea428bc556.gif)

`<Pressable android_ripple={{borderless: false}}>` in this PR

![SVID_20200404_122754_1](https://user-images.githubusercontent.com/1566403/78424986-8bf9b000-7671-11ea-9804-37cd58dbb61e.gif)

Differential Revision: D20952026

Pulled By: TheSavior

fbshipit-source-id: df2b95fc6f20d7e958e91805b1a928c4f85904f1
2020-04-09 15:40:47 -07:00

105 lines
2.9 KiB
JavaScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
import invariant from 'invariant';
import {Commands} from '../View/ViewNativeComponent';
import type {ColorValue} from '../../StyleSheet/StyleSheetTypes';
import type {PressEvent} from '../../Types/CoreEventTypes';
import {Platform, View, processColor} from 'react-native';
import * as React from 'react';
import {useMemo} from 'react';
type NativeBackgroundProp = $ReadOnly<{|
type: 'RippleAndroid',
color: ?number,
borderless: boolean,
rippleRadius: ?number,
|}>;
export type RippleConfig = {|
color?: ColorValue,
borderless?: boolean,
radius?: number,
|};
/**
* Provides the event handlers and props for configuring the ripple effect on
* supported versions of Android.
*/
export default function useAndroidRippleForView(
rippleConfig: ?RippleConfig,
viewRef: {|current: null | React.ElementRef<typeof View>|},
): ?$ReadOnly<{|
onPressIn: (event: PressEvent) => void,
onPressMove: (event: PressEvent) => void,
onPressOut: (event: PressEvent) => void,
viewProps: $ReadOnly<{|
nativeBackgroundAndroid: NativeBackgroundProp,
|}>,
|}> {
const {color, borderless, radius} = rippleConfig ?? {};
return useMemo(() => {
if (
Platform.OS === 'android' &&
Platform.Version >= 21 &&
(color != null || borderless != null || radius != null)
) {
const processedColor = processColor(color);
invariant(
processedColor == null || typeof processedColor === 'number',
'Unexpected color given for Ripple color',
);
return {
viewProps: {
// Consider supporting `nativeForegroundAndroid`
nativeBackgroundAndroid: {
type: 'RippleAndroid',
color: processedColor,
borderless: borderless === true,
rippleRadius: radius,
},
},
onPressIn(event: PressEvent): void {
const view = viewRef.current;
if (view != null) {
Commands.setPressed(view, true);
Commands.hotspotUpdate(
view,
event.nativeEvent.locationX ?? 0,
event.nativeEvent.locationY ?? 0,
);
}
},
onPressMove(event: PressEvent): void {
const view = viewRef.current;
if (view != null) {
Commands.hotspotUpdate(
view,
event.nativeEvent.locationX ?? 0,
event.nativeEvent.locationY ?? 0,
);
}
},
onPressOut(event: PressEvent): void {
const view = viewRef.current;
if (view != null) {
Commands.setPressed(view, false);
}
},
};
}
return null;
}, [color, borderless, radius, viewRef]);
}