Skip to content

Commit cbdf92e

Browse files
committed
feat(rich-text): add focus and blur
1 parent af6d737 commit cbdf92e

7 files changed

Lines changed: 81 additions & 0 deletions

File tree

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ import RichTextInput, { type RichTextRef, type RichTextChangeEvent } from 'reac
3939

4040
const ref = useRef<RichTextRef>(null);
4141

42+
const handleFocus = () => {
43+
ref.current?.focus();
44+
};
45+
46+
const handleBlur = () => {
47+
ref.current?.blur();
48+
};
49+
4250
const handleUnderlinePress = () => {
4351
ref.current?.toggleUnderline();
4452
};
@@ -85,6 +93,7 @@ const handleInsertText = () => {
8593
5. Return text without markdown (iOS, Android)
8694
6. Add method that returns rich text in HTML (iOS, Android)
8795
7. Add method to set default text (Android)
96+
8. Add focus and blur methods (iOS, Android)
8897
8998
# TODO
9099

android/src/main/java/com/richtextinput/RichTextInputViewManager.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package com.richtextinput
22

33
import android.R.attr.htmlDescription
4+
import android.app.Activity
45
import android.graphics.Typeface
56
import android.text.Spannable
67
import android.text.style.StrikethroughSpan
78
import android.text.style.StyleSpan
89
import android.text.style.UnderlineSpan
10+
import android.view.inputmethod.InputMethodManager
911
import android.widget.EditText
1012
import androidx.core.text.HtmlCompat
1113
import androidx.core.text.toHtml
@@ -68,6 +70,12 @@ class RichTextInputViewManager : SimpleViewManager<EditText>() {
6870
Assertions.assertNotNull(root)
6971

7072
when (commandId) {
73+
"focus" -> {
74+
focus(root)
75+
}
76+
"blur" -> {
77+
blur(root)
78+
}
7179
"toggleBold" -> {
7280
toggleBold(root)
7381
}
@@ -92,6 +100,20 @@ class RichTextInputViewManager : SimpleViewManager<EditText>() {
92100
super.receiveCommand(root, commandId, args)
93101
}
94102

103+
fun focus(editText: EditText) {
104+
editText.requestFocus()
105+
106+
val inputMethodManager = editText.context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
107+
inputMethodManager.showSoftInput(editText, 0)
108+
}
109+
110+
fun blur(editText: EditText) {
111+
editText.clearFocus()
112+
113+
val inputMethodManager = editText.context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
114+
inputMethodManager.hideSoftInputFromWindow(editText.windowToken, 0)
115+
}
116+
95117
fun insertText(editText: EditText, text: String) {
96118
val spannedText = HtmlCompat.fromHtml(text, HtmlCompat.FROM_HTML_MODE_LEGACY)
97119
val trimmedText = spannedText.toString().trim()

example/src/App.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ function App(): React.JSX.Element {
4343
ref.current?.insertText('<p dir="ltr"><u>some</u> <b>text</b></p>');
4444
};
4545

46+
const handleFocus = () => {
47+
ref.current?.focus();
48+
};
49+
50+
const handleBlur = () => {
51+
ref.current?.blur();
52+
};
53+
4654
return (
4755
<SafeAreaView style={styles.container}>
4856
<RichTextInput
@@ -51,6 +59,8 @@ function App(): React.JSX.Element {
5159
placeholder="I HATE ASDASDSA"
5260
onChange={handleChange}
5361
/>
62+
<Button title="Focus" onPress={handleFocus} />
63+
<Button title="Blur" onPress={handleBlur} />
5464
<Button title="Underline" onPress={handleUnderlinePress} />
5565
<Button title="Bold" onPress={handleBoldPress} />
5666
<Button title="Strike" onPress={handleStrikePress} />

ios/RichTextInput.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ class RichTextInput: UITextView, UIEditMenuInteractionDelegate {
4343
actions.insert(customMenu, at: 0)
4444
return UIMenu(children: actions)
4545
}
46+
47+
func focus() {
48+
reactFocus()
49+
}
50+
51+
func blur() {
52+
reactBlur()
53+
}
4654

4755
// TODO: styles are getting lost if you enable/reenable them, bug, needs fixing
4856
func toggleStyle(style: NSAttributedString.Key) {

ios/RichTextInputViewManager.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ @interface RCT_EXTERN_MODULE(RichTextInputViewManager, RCTViewManager)
1414
RCT_EXTERN_METHOD(toggleStrike:(nonnull NSNumber *)node)
1515
RCT_EXTERN_METHOD(toggleItalic:(nonnull NSNumber *)node)
1616
RCT_EXTERN_METHOD(setPlaceholder:(nonnull NSNumber *)node placeholder:(nonnull NSString *)placeholder)
17+
RCT_EXTERN_METHOD(focus:(nonnull NSNumber *)node)
18+
RCT_EXTERN_METHOD(blur:(nonnull NSNumber *)node)
1719

1820
RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock)
1921

ios/RichTextInputViewManager.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,20 @@ public class RichTextInputViewManager: RCTViewManager, UITextViewDelegate {
4848
richTextView.toggleStyle(style: NSAttributedString.Key.underlineStyle)
4949
}, onNode: node)
5050
}
51+
52+
@objc
53+
func focus(_ node: NSNumber) {
54+
executeBlock({ (richTextView) in
55+
richTextView.focus()
56+
}, onNode: node)
57+
}
58+
59+
@objc
60+
func blur(_ node: NSNumber) {
61+
executeBlock({ (richTextView) in
62+
richTextView.blur()
63+
}, onNode: node)
64+
}
5165

5266
@objc
5367
func toggleStrike(_ node: NSNumber) {

src/index.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ export interface RichTextRef {
3737
toggleUnderline: Function;
3838
getHTML: () => Promise<string>;
3939
insertText: (text: string) => void;
40+
focus: Function;
41+
blur: Function;
4042
}
4143

4244
const ComponentName = 'RichTextInputView';
@@ -65,6 +67,20 @@ const RichTextInput = forwardRef<RichTextRef, RichTextProps>(
6567

6668
useImperativeHandle(ref, () => {
6769
return {
70+
focus: () => {
71+
UIManager.dispatchViewManagerCommand(
72+
findNodeHandle(inputRef.current as unknown as Component),
73+
'focus',
74+
[]
75+
);
76+
},
77+
blur: () => {
78+
UIManager.dispatchViewManagerCommand(
79+
findNodeHandle(inputRef.current as unknown as Component),
80+
'blur',
81+
[]
82+
);
83+
},
6884
toggleBold: () => {
6985
UIManager.dispatchViewManagerCommand(
7086
findNodeHandle(inputRef.current as unknown as Component),

0 commit comments

Comments
 (0)