Add selectionColor prop for Text on Android
Summary: **Motivation** Customizing the selection color allows to use brand colors in the app. The PR implements a `selectionColor` prop for `Text` component similar to `TextInput`. **Test plan (required)** Run UIExplorer example with the changes and verify everything works fine. ![image](https://cloud.githubusercontent.com/assets/1174278/22023258/70197d84-dceb-11e6-8662-2879d78d14d4.png) cc brentvatne Closes https://github.com/facebook/react-native/pull/11947 Differential Revision: D4430265 fbshipit-source-id: 462f16548d93ab03aadb27d6f12acf90842627ab
This commit is contained in:
parent
81c33b542d
commit
72be2d35cc
|
@ -386,10 +386,15 @@ class TextExample extends React.Component {
|
|||
</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="selectable attribute">
|
||||
<Text selectable={true}>
|
||||
<Text selectable>
|
||||
This text is selectable if you click-and-hold, and will offer the native Android selection menus.
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="selectionColor attribute">
|
||||
<Text selectable selectionColor="orange">
|
||||
This text will have a orange highlight on selection.
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
<UIExplorerBlock title="Inline images">
|
||||
<Text>
|
||||
This text contains an inline image <Image source={require('./flux.png')}/>. Neat, huh?
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
*/
|
||||
'use strict';
|
||||
|
||||
const ColorPropType = require('ColorPropType');
|
||||
const EdgeInsetsPropType = require('EdgeInsetsPropType');
|
||||
const NativeMethodsMixin = require('NativeMethodsMixin');
|
||||
const Platform = require('Platform');
|
||||
|
@ -20,9 +21,12 @@ const StyleSheetPropType = require('StyleSheetPropType');
|
|||
const TextStylePropTypes = require('TextStylePropTypes');
|
||||
const Touchable = require('Touchable');
|
||||
|
||||
const processColor = require('processColor');
|
||||
const createReactNativeComponentClass = require('createReactNativeComponentClass');
|
||||
const mergeFast = require('mergeFast');
|
||||
|
||||
const { PropTypes } = React;
|
||||
|
||||
const stylePropType = StyleSheetPropType(TextStylePropTypes);
|
||||
|
||||
const viewConfig = {
|
||||
|
@ -32,6 +36,7 @@ const viewConfig = {
|
|||
ellipsizeMode: true,
|
||||
allowFontScaling: true,
|
||||
selectable: true,
|
||||
selectionColor: true,
|
||||
adjustsFontSizeToFit: true,
|
||||
minimumFontScale: true,
|
||||
textBreakStrategy: true,
|
||||
|
@ -109,7 +114,7 @@ const Text = React.createClass({
|
|||
*
|
||||
* > `clip` is working only for iOS
|
||||
*/
|
||||
ellipsizeMode: React.PropTypes.oneOf(['head', 'middle', 'tail', 'clip']),
|
||||
ellipsizeMode: PropTypes.oneOf(['head', 'middle', 'tail', 'clip']),
|
||||
/**
|
||||
* Used to truncate the text with an ellipsis after computing the text
|
||||
* layout, including line wrapping, such that the total number of lines
|
||||
|
@ -117,31 +122,31 @@ const Text = React.createClass({
|
|||
*
|
||||
* This prop is commonly used with `ellipsizeMode`.
|
||||
*/
|
||||
numberOfLines: React.PropTypes.number,
|
||||
numberOfLines: PropTypes.number,
|
||||
/**
|
||||
* Set text break strategy on Android API Level 23+, possible values are `simple`, `highQuality`, `balanced`
|
||||
* The default value is `highQuality`.
|
||||
* @platform android
|
||||
*/
|
||||
textBreakStrategy: React.PropTypes.oneOf(['simple', 'highQuality', 'balanced']),
|
||||
textBreakStrategy: PropTypes.oneOf(['simple', 'highQuality', 'balanced']),
|
||||
/**
|
||||
* Invoked on mount and layout changes with
|
||||
*
|
||||
* `{nativeEvent: {layout: {x, y, width, height}}}`
|
||||
*/
|
||||
onLayout: React.PropTypes.func,
|
||||
onLayout: PropTypes.func,
|
||||
/**
|
||||
* This function is called on press.
|
||||
*
|
||||
* e.g., `onPress={() => console.log('1st')}``
|
||||
*/
|
||||
onPress: React.PropTypes.func,
|
||||
onPress: PropTypes.func,
|
||||
/**
|
||||
* This function is called on long press.
|
||||
*
|
||||
* e.g., `onLongPress={this.increaseSize}>``
|
||||
*/
|
||||
onLongPress: React.PropTypes.func,
|
||||
onLongPress: PropTypes.func,
|
||||
/**
|
||||
* When the scroll view is disabled, this defines how far your touch may
|
||||
* move off of the button, before deactivating the button. Once deactivated,
|
||||
|
@ -153,24 +158,28 @@ const Text = React.createClass({
|
|||
/**
|
||||
* Lets the user select text, to use the native copy and paste functionality.
|
||||
*/
|
||||
selectable: React.PropTypes.bool,
|
||||
selectable: PropTypes.bool,
|
||||
/**
|
||||
* The highlight color of the text.
|
||||
* @platform android
|
||||
*/
|
||||
selectionColor: ColorPropType,
|
||||
/**
|
||||
* When `true`, no visual change is made when text is pressed down. By
|
||||
* default, a gray oval highlights the text on press down.
|
||||
*
|
||||
* @platform ios
|
||||
*/
|
||||
suppressHighlighting: React.PropTypes.bool,
|
||||
suppressHighlighting: PropTypes.bool,
|
||||
style: stylePropType,
|
||||
/**
|
||||
* Used to locate this view in end-to-end tests.
|
||||
*/
|
||||
testID: React.PropTypes.string,
|
||||
testID: PropTypes.string,
|
||||
/**
|
||||
* Specifies whether fonts should scale to respect Text Size accessibility setting on iOS. The
|
||||
* default is `true`.
|
||||
*/
|
||||
allowFontScaling: React.PropTypes.bool,
|
||||
allowFontScaling: PropTypes.bool,
|
||||
/**
|
||||
* When set to `true`, indicates that the view is an accessibility element. The default value
|
||||
* for a `Text` element is `true`.
|
||||
|
@ -179,18 +188,18 @@ const Text = React.createClass({
|
|||
* [Accessibility guide](/react-native/docs/accessibility.html#accessible-ios-android)
|
||||
* for more information.
|
||||
*/
|
||||
accessible: React.PropTypes.bool,
|
||||
accessible: PropTypes.bool,
|
||||
/**
|
||||
* Specifies whether font should be scaled down automatically to fit given style constraints.
|
||||
* @platform ios
|
||||
*/
|
||||
adjustsFontSizeToFit: React.PropTypes.bool,
|
||||
adjustsFontSizeToFit: PropTypes.bool,
|
||||
|
||||
/**
|
||||
* Specifies smallest possible scale a font can reach when adjustsFontSizeToFit is enabled. (values 0.01-1.0).
|
||||
* @platform ios
|
||||
*/
|
||||
minimumFontScale: React.PropTypes.number,
|
||||
minimumFontScale: PropTypes.number,
|
||||
},
|
||||
getDefaultProps(): Object {
|
||||
return {
|
||||
|
@ -210,10 +219,10 @@ const Text = React.createClass({
|
|||
return {isInAParentText: true};
|
||||
},
|
||||
childContextTypes: {
|
||||
isInAParentText: React.PropTypes.bool
|
||||
isInAParentText: PropTypes.bool
|
||||
},
|
||||
contextTypes: {
|
||||
isInAParentText: React.PropTypes.bool
|
||||
isInAParentText: PropTypes.bool
|
||||
},
|
||||
/**
|
||||
* Only assigned if touch is needed.
|
||||
|
@ -317,6 +326,12 @@ const Text = React.createClass({
|
|||
isHighlighted: this.state.isHighlighted,
|
||||
};
|
||||
}
|
||||
if (newProps.selectionColor != null) {
|
||||
newProps = {
|
||||
...newProps,
|
||||
selectionColor: processColor(newProps.selectionColor)
|
||||
};
|
||||
}
|
||||
if (Touchable.TOUCH_TARGET_DEBUG && newProps.onPress) {
|
||||
newProps = {
|
||||
...newProps,
|
||||
|
|
|
@ -9,25 +9,25 @@
|
|||
|
||||
package com.facebook.react.views.text;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import android.text.Spannable;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.facebook.yoga.YogaConstants;
|
||||
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
||||
import com.facebook.react.common.annotations.VisibleForTesting;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.facebook.react.uimanager.BaseViewManager;
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||
import com.facebook.react.uimanager.Spacing;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
import com.facebook.react.uimanager.ViewDefaults;
|
||||
import com.facebook.react.uimanager.ViewProps;
|
||||
import com.facebook.react.common.annotations.VisibleForTesting;
|
||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||
import com.facebook.react.uimanager.annotations.ReactPropGroup;
|
||||
import com.facebook.yoga.YogaConstants;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Manages instances of spannable {@link TextView}.
|
||||
|
@ -96,6 +96,15 @@ public class ReactTextViewManager extends BaseViewManager<ReactTextView, ReactTe
|
|||
view.setTextIsSelectable(isSelectable);
|
||||
}
|
||||
|
||||
@ReactProp(name = "selectionColor", customType = "Color")
|
||||
public void setSelectionColor(ReactTextView view, @Nullable Integer color) {
|
||||
if (color == null) {
|
||||
view.setHighlightColor(DefaultStyleValuesUtil.getDefaultTextColorHighlight(view.getContext()));
|
||||
} else {
|
||||
view.setHighlightColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactPropGroup(names = {
|
||||
ViewProps.BORDER_RADIUS,
|
||||
ViewProps.BORDER_TOP_LEFT_RADIUS,
|
||||
|
|
Loading…
Reference in New Issue