Permalink
Browse files

Fix text input spans

Differential Revision: D2626072

fb-gh-sync-id: 35087d65b8f4a52e44fedc229058c3f88827e539
  • Loading branch information...
andreicoman11 authored and facebook-github-bot-9 committed Nov 6, 2015
1 parent 7b2cd03 commit de586bfa186289114974674bc2aece462f40393e
@@ -91,6 +91,60 @@ class RewriteExample extends React.Component {
}
}
+class TokenizedTextExample extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {text: 'Hello #World'};
+ }
+ render() {
+
+ //define delimiter
+ let delimiter = /\s+/;
+
+ //split string
+ let _text = this.state.text;
+ let token, index, parts = [];
+ while (_text) {
+ delimiter.lastIndex = 0;
+ token = delimiter.exec(_text);
+ if (token === null) {
+ break;
+ }
+ index = token.index;
+ if (token[0].length === 0) {
+ index = 1;
+ }
+ parts.push(_text.substr(0, index));
+ parts.push(token[0]);
+ index = index + token[0].length;
+ _text = _text.slice(index);
+ }
+ parts.push(_text);
+
+ //highlight hashtags
+ parts = parts.map((text) => {
+ if (/^#/.test(text)) {
+ return <Text key={text} style={styles.hashtag}>{text}</Text>;
+ } else {
+ return text;
+ }
+ });
+
+ return (
+ <View>
+ <TextInput
+ multiline={true}
+ style={styles.multiline}
+ onChangeText={(text) => {
+ this.setState({text});
+ }}>
+ <Text>{parts}</Text>
+ </TextInput>
+ </View>
+ );
+ }
+}
+
var styles = StyleSheet.create({
multiline: {
height: 60,
@@ -109,6 +163,10 @@ var styles = StyleSheet.create({
singleLineWithHeightTextInput: {
height: 30,
},
+ hashtag: {
+ color: 'blue',
+ fontWeight: 'bold',
+ },
});
exports.title = '<TextInput>';
@@ -322,4 +380,10 @@ exports.examples = [
);
}
},
+ {
+ title: 'Attributed text',
+ render: function() {
+ return <TokenizedTextExample />;
+ }
+ },
];
@@ -20,12 +20,17 @@
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextWatcher;
+import android.text.style.AbsoluteSizeSpan;
+import android.text.style.BackgroundColorSpan;
+import android.text.style.ForegroundColorSpan;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import com.facebook.infer.annotation.Assertions;
+import com.facebook.react.views.text.CustomStyleSpan;
+import com.facebook.react.views.text.ReactTagSpan;
/**
* A wrapper around the EditText that lets us better control what happens when an EditText gets
@@ -204,6 +209,15 @@ public void maybeSetText(ReactTextUpdate reactTextUpdate) {
private void manageSpans(SpannableStringBuilder spannableStringBuilder) {
Object[] spans = getText().getSpans(0, length(), Object.class);
for (int spanIdx = 0; spanIdx < spans.length; spanIdx++) {
+ // Remove all styling spans we might have previously set
+ if (ForegroundColorSpan.class.isInstance(spans[spanIdx]) ||
+ BackgroundColorSpan.class.isInstance(spans[spanIdx]) ||
+ AbsoluteSizeSpan.class.isInstance(spans[spanIdx]) ||
+ CustomStyleSpan.class.isInstance(spans[spanIdx]) ||
+ ReactTagSpan.class.isInstance(spans[spanIdx])) {
+ getText().removeSpan(spans[spanIdx]);
+ }
+
if ((getText().getSpanFlags(spans[spanIdx]) & Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) !=
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) {
continue;
@@ -16,8 +16,9 @@
/**
* Event emitted by EditText native view when text changes.
+ * VisibleForTesting from {@link TextInputEventsTestCase}.
*/
-/* package */ class ReactTextChangedEvent extends Event<ReactTextChangedEvent> {
+public class ReactTextChangedEvent extends Event<ReactTextChangedEvent> {
public static final String EVENT_NAME = "topChange";
@@ -16,8 +16,9 @@
/**
* Event emitted by EditText native view when text changes.
+ * VisibleForTesting from {@link TextInputEventsTestCase}.
*/
-/* package */ class ReactTextInputEvent extends Event<ReactTextInputEvent> {
+public class ReactTextInputEvent extends Event<ReactTextInputEvent> {
public static final String EVENT_NAME = "topTextInput";

0 comments on commit de586bf

Please sign in to comment.