From f43c9316e184b7a569804c2805458196b2875dd5 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 20 Jan 2020 03:06:14 -0800 Subject: [PATCH] Add blur and focus native commands to TextInput Summary: Add Native Commands handlers to TextInput. It is intentionally done in a way so that it can be easily swapped for codegened implementation once we properly type TextInput. We also add native commands to view managers for backwards compatibility. Changelog: [Internal] Reviewed By: TheSavior, shergin Differential Revision: D19412026 fbshipit-source-id: 8dc64275cf1da599b1bd5992a41035d51dd4148f --- .../RCTMultilineTextInputViewManager.m | 1 - .../TextInput/RCTBaseTextInputViewManager.m | 16 ++++++ .../TextInput/RCTTextInputComponentView.mm | 20 ++++++- .../TextInput/RCTTextInputNativeCommands.h | 53 +++++++++++++++++++ 4 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h diff --git a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m index 3ce76b116d..6f9696029b 100644 --- a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m +++ b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m @@ -6,7 +6,6 @@ */ #import - #import @implementation RCTMultilineTextInputViewManager diff --git a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m index 788657c6c8..3d289464bd 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m @@ -100,6 +100,22 @@ RCT_CUSTOM_VIEW_PROPERTY(multiline, BOOL, UIView) lazilyLoadIfNecessary:YES]]; } +RCT_EXPORT_METHOD(focus : (nonnull NSNumber *)viewTag) +{ + [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { + UIView *view = viewRegistry[viewTag]; + [view reactFocus]; + }]; +} + +RCT_EXPORT_METHOD(blur : (nonnull NSNumber *)viewTag) +{ + [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { + UIView *view = viewRegistry[viewTag]; + [view reactBlur]; + }]; +} + #pragma mark - RCTUIManagerObserver - (void)uiManagerWillPerformMounting:(__unused RCTUIManager *)uiManager diff --git a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm index 532cc5754e..a81291d5a2 100644 --- a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm @@ -17,11 +17,12 @@ #import #import "RCTConversions.h" +#import "RCTTextInputNativeCommands.h" #import "RCTTextInputUtils.h" using namespace facebook::react; -@interface RCTTextInputComponentView () +@interface RCTTextInputComponentView () @end @implementation RCTTextInputComponentView { @@ -342,4 +343,21 @@ using namespace facebook::react; return AttributedString::Range{(int)start, (int)(end - start)}; } +#pragma mark - Native Commands + +- (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args +{ + RCTTextInputHandleCommand(self, commandName, args); +} + +- (void)focus +{ + [_backedTextInputView becomeFirstResponder]; +} + +- (void)blur +{ + [_backedTextInputView resignFirstResponder]; +} + @end diff --git a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h new file mode 100644 index 0000000000..9fe35851a7 --- /dev/null +++ b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h @@ -0,0 +1,53 @@ +/* + * 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. + */ + +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@protocol RCTTextInputViewProtocol +- (void)focus; +- (void)blur; +@end + +RCT_EXTERN inline void +RCTTextInputHandleCommand(id componentView, NSString const *commandName, NSArray const *args) +{ + if ([commandName isEqualToString:@"focus"]) { +#if RCT_DEBUG + if ([args count] != 0) { + RCTLogError( + @"%@ command %@ received %d arguments, expected %d.", @"TextInput", commandName, (int)[args count], 0); + return; + } +#endif + + [componentView focus]; + return; + } + + if ([commandName isEqualToString:@"blur"]) { +#if RCT_DEBUG + if ([args count] != 0) { + RCTLogError( + @"%@ command %@ received %d arguments, expected %d.", @"TextInput", commandName, (int)[args count], 0); + return; + } +#endif + + [componentView blur]; + return; + } + +#if RCT_DEBUG + RCTLogError(@"%@ received command %@, which is not a supported command.", @"TextInput", commandName); +#endif +} + +NS_ASSUME_NONNULL_END