From 2dd2529b3ab3ace39136a6e24c09f80ae421a17e Mon Sep 17 00:00:00 2001 From: Alex Hinson Date: Tue, 27 Feb 2018 17:29:40 -0800 Subject: [PATCH] Add option to hide context menu for TextInput #17335 Summary: There is currently no way to disable to context menu that automatically appears over a TextInput. This is especially troublesome if you would like to disable the user from pasting text into certain fields. This PR adds a `contextMenuHidden` property to TextInput that will hide it. I'm not sure if testing is necessary here. I would be happy to investigate further on how this would be tested, if deemed necessary! https://github.com/facebook/react-native-website/pull/95 [FEATURE][TextInput] - Added `contextMenuHidden` property Closes https://github.com/facebook/react-native/pull/18125 Differential Revision: D7101888 Pulled By: hramos fbshipit-source-id: fe36603a3fbdcefbd644251a7ea894ac7e23e5b8 --- Libraries/Components/TextInput/TextInput.js | 4 ++++ .../Text/TextInput/Multiline/RCTUITextView.h | 1 + .../Text/TextInput/Multiline/RCTUITextView.m | 17 ++++++++++++++--- .../TextInput/RCTBaseTextInputViewManager.m | 1 + .../Text/TextInput/Singleline/RCTUITextField.h | 1 + .../Text/TextInput/Singleline/RCTUITextField.m | 11 +++++++++++ .../views/textinput/ReactTextInputManager.java | 10 ++++++++++ 7 files changed, 42 insertions(+), 3 deletions(-) diff --git a/Libraries/Components/TextInput/TextInput.js b/Libraries/Components/TextInput/TextInput.js index 57dc866b9dc44a..383e7e6ac35027 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -590,6 +590,10 @@ const TextInput = createReactClass({ * This property is supported only for single-line TextInput component on iOS. */ caretHidden: PropTypes.bool, + /* + * If `true`, contextMenuHidden is hidden. The default value is `false`. + */ + contextMenuHidden: PropTypes.bool, /** * An optional identifier which links a custom InputAccessoryView to * this text input. The InputAccessoryView is rendered above the diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.h b/Libraries/Text/TextInput/Multiline/RCTUITextView.h index c460d7f1e47b0f..cb817cba754039 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.h +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.h @@ -23,6 +23,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, weak) id textInputDelegate; +@property (nonatomic, assign) BOOL contextMenuHidden; @property (nonatomic, assign, readonly) BOOL textWasPasted; @property (nonatomic, copy, nullable) NSString *placeholder; @property (nonatomic, strong, nullable) UIColor *placeholderColor; diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index 80d49a5f5aef7d..992a1a8abfc602 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -58,19 +58,19 @@ - (void)dealloc - (NSString *)accessibilityLabel { NSMutableString *accessibilityLabel = [NSMutableString new]; - + NSString *superAccessibilityLabel = [super accessibilityLabel]; if (superAccessibilityLabel.length > 0) { [accessibilityLabel appendString:superAccessibilityLabel]; } - + if (self.placeholder.length > 0 && self.attributedText.string.length == 0) { if (accessibilityLabel.length > 0) { [accessibilityLabel appendString:@" "]; } [accessibilityLabel appendString:self.placeholder]; } - + return accessibilityLabel; } @@ -228,6 +228,17 @@ - (CGSize)fixedSizeThatFits:(CGSize)size return [_detachedTextView sizeThatFits:size]; } +#pragma mark - Context Menu + +- (BOOL)canPerformAction:(SEL)action withSender:(id)sender +{ + if (_contextMenuHidden) { + return NO; + } + + return [super canPerformAction:action withSender:sender]; +} + #pragma mark - Placeholder - (void)invalidatePlaceholderVisibility diff --git a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m index 745fd83cb60967..aaead20b0b9c1c 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m @@ -36,6 +36,7 @@ @implementation RCTBaseTextInputViewManager RCT_REMAP_VIEW_PROPERTY(autoCapitalize, backedTextInputView.autocapitalizationType, UITextAutocapitalizationType) RCT_REMAP_VIEW_PROPERTY(autoCorrect, backedTextInputView.autocorrectionType, UITextAutocorrectionType) +RCT_REMAP_VIEW_PROPERTY(contextMenuHidden, backedTextInputView.contextMenuHidden, BOOL) RCT_REMAP_VIEW_PROPERTY(editable, backedTextInputView.editable, BOOL) RCT_REMAP_VIEW_PROPERTY(enablesReturnKeyAutomatically, backedTextInputView.enablesReturnKeyAutomatically, BOOL) RCT_REMAP_VIEW_PROPERTY(keyboardAppearance, backedTextInputView.keyboardAppearance, UIKeyboardAppearance) diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.h b/Libraries/Text/TextInput/Singleline/RCTUITextField.h index b56d6a81df6317..a2e7a0e0c61bd6 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.h +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.h @@ -21,6 +21,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, weak) id textInputDelegate; @property (nonatomic, assign) BOOL caretHidden; +@property (nonatomic, assign) BOOL contextMenuHidden; @property (nonatomic, assign, readonly) BOOL textWasPasted; @property (nonatomic, strong, nullable) UIColor *placeholderColor; @property (nonatomic, assign) UIEdgeInsets textContainerInset; diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index 281bd63945deeb..83e7603ae83506 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -85,6 +85,17 @@ - (void)setEditable:(BOOL)editable self.enabled = editable; } +#pragma mark - Context Menu + +- (BOOL)canPerformAction:(SEL)action withSender:(id)sender +{ + if (_contextMenuHidden) { + return NO; + } + + return [super canPerformAction:action withSender:sender]; +} + #pragma mark - Caret Manipulation - (CGRect)caretRectForPosition:(UITextPosition *)position diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java index e4224eaac01016..637027140ec010 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java @@ -378,6 +378,16 @@ public void setCaretHidden(ReactEditText view, boolean caretHidden) { view.setCursorVisible(!caretHidden); } + @ReactProp(name = "contextMenuHidden", defaultBoolean = false) + public void setContextMenuHidden(ReactEditText view, boolean contextMenuHidden) { + final boolean _contextMenuHidden = contextMenuHidden; + view.setOnLongClickListener(new View.OnLongClickListener() { + public boolean onLongClick(View v) { + return _contextMenuHidden; + }; + }); + } + @ReactProp(name = "selectTextOnFocus", defaultBoolean = false) public void setSelectTextOnFocus(ReactEditText view, boolean selectTextOnFocus) { view.setSelectAllOnFocus(selectTextOnFocus);