1/* 2 * Copyright (c) Meta Platforms, Inc. and affiliates. 3 * 4 * This source code is licensed under the MIT license found in the 5 * LICENSE file in the root directory of this source tree. 6 */ 7 8#import <ABI47_0_0React/ABI47_0_0RCTBaseTextInputViewManager.h> 9 10#import <ABI47_0_0React/ABI47_0_0RCTBridge.h> 11#import <ABI47_0_0React/ABI47_0_0RCTConvert.h> 12#import <ABI47_0_0React/ABI47_0_0RCTFont.h> 13#import <ABI47_0_0React/ABI47_0_0RCTShadowView+Layout.h> 14#import <ABI47_0_0React/ABI47_0_0RCTShadowView.h> 15#import <ABI47_0_0React/ABI47_0_0RCTUIManager.h> 16#import <ABI47_0_0React/ABI47_0_0RCTUIManagerUtils.h> 17#import <ABI47_0_0React/ABI47_0_0RCTUIManagerObserverCoordinator.h> 18 19#import <ABI47_0_0React/ABI47_0_0RCTBaseTextInputShadowView.h> 20#import <ABI47_0_0React/ABI47_0_0RCTBaseTextInputView.h> 21#import <ABI47_0_0React/ABI47_0_0RCTConvert+Text.h> 22 23@interface ABI47_0_0RCTBaseTextInputViewManager () <ABI47_0_0RCTUIManagerObserver> 24 25@end 26 27@implementation ABI47_0_0RCTBaseTextInputViewManager 28{ 29 NSHashTable<ABI47_0_0RCTBaseTextInputShadowView *> *_shadowViews; 30} 31 32ABI47_0_0RCT_EXPORT_MODULE() 33 34#pragma mark - Unified <TextInput> properties 35 36ABI47_0_0RCT_REMAP_VIEW_PROPERTY(autoCapitalize, backedTextInputView.autocapitalizationType, UITextAutocapitalizationType) 37ABI47_0_0RCT_REMAP_VIEW_PROPERTY(autoCorrect, backedTextInputView.autocorrectionType, UITextAutocorrectionType) 38ABI47_0_0RCT_REMAP_VIEW_PROPERTY(contextMenuHidden, backedTextInputView.contextMenuHidden, BOOL) 39ABI47_0_0RCT_REMAP_VIEW_PROPERTY(editable, backedTextInputView.editable, BOOL) 40ABI47_0_0RCT_REMAP_VIEW_PROPERTY(enablesReturnKeyAutomatically, backedTextInputView.enablesReturnKeyAutomatically, BOOL) 41ABI47_0_0RCT_REMAP_VIEW_PROPERTY(keyboardAppearance, backedTextInputView.keyboardAppearance, UIKeyboardAppearance) 42ABI47_0_0RCT_REMAP_VIEW_PROPERTY(placeholder, backedTextInputView.placeholder, NSString) 43ABI47_0_0RCT_REMAP_VIEW_PROPERTY(placeholderTextColor, backedTextInputView.placeholderColor, UIColor) 44ABI47_0_0RCT_REMAP_VIEW_PROPERTY(returnKeyType, backedTextInputView.returnKeyType, UIReturnKeyType) 45ABI47_0_0RCT_REMAP_VIEW_PROPERTY(selectionColor, backedTextInputView.tintColor, UIColor) 46ABI47_0_0RCT_REMAP_VIEW_PROPERTY(spellCheck, backedTextInputView.spellCheckingType, UITextSpellCheckingType) 47ABI47_0_0RCT_REMAP_VIEW_PROPERTY(caretHidden, backedTextInputView.caretHidden, BOOL) 48ABI47_0_0RCT_REMAP_VIEW_PROPERTY(clearButtonMode, backedTextInputView.clearButtonMode, UITextFieldViewMode) 49ABI47_0_0RCT_REMAP_VIEW_PROPERTY(scrollEnabled, backedTextInputView.scrollEnabled, BOOL) 50ABI47_0_0RCT_REMAP_VIEW_PROPERTY(secureTextEntry, backedTextInputView.secureTextEntry, BOOL) 51ABI47_0_0RCT_EXPORT_VIEW_PROPERTY(autoFocus, BOOL) 52ABI47_0_0RCT_EXPORT_VIEW_PROPERTY(blurOnSubmit, BOOL) 53ABI47_0_0RCT_EXPORT_VIEW_PROPERTY(clearTextOnFocus, BOOL) 54ABI47_0_0RCT_EXPORT_VIEW_PROPERTY(keyboardType, UIKeyboardType) 55ABI47_0_0RCT_EXPORT_VIEW_PROPERTY(showSoftInputOnFocus, BOOL) 56ABI47_0_0RCT_EXPORT_VIEW_PROPERTY(maxLength, NSNumber) 57ABI47_0_0RCT_EXPORT_VIEW_PROPERTY(selectTextOnFocus, BOOL) 58ABI47_0_0RCT_EXPORT_VIEW_PROPERTY(selection, ABI47_0_0RCTTextSelection) 59ABI47_0_0RCT_EXPORT_VIEW_PROPERTY(inputAccessoryViewID, NSString) 60ABI47_0_0RCT_EXPORT_VIEW_PROPERTY(textContentType, NSString) 61ABI47_0_0RCT_EXPORT_VIEW_PROPERTY(passwordRules, NSString) 62 63ABI47_0_0RCT_EXPORT_VIEW_PROPERTY(onChange, ABI47_0_0RCTBubblingEventBlock) 64ABI47_0_0RCT_EXPORT_VIEW_PROPERTY(onKeyPressSync, ABI47_0_0RCTDirectEventBlock) 65ABI47_0_0RCT_EXPORT_VIEW_PROPERTY(onChangeSync, ABI47_0_0RCTDirectEventBlock) 66ABI47_0_0RCT_EXPORT_VIEW_PROPERTY(onSelectionChange, ABI47_0_0RCTDirectEventBlock) 67ABI47_0_0RCT_EXPORT_VIEW_PROPERTY(onTextInput, ABI47_0_0RCTDirectEventBlock) 68ABI47_0_0RCT_EXPORT_VIEW_PROPERTY(onScroll, ABI47_0_0RCTDirectEventBlock) 69 70ABI47_0_0RCT_EXPORT_VIEW_PROPERTY(mostRecentEventCount, NSInteger) 71 72ABI47_0_0RCT_EXPORT_SHADOW_PROPERTY(text, NSString) 73ABI47_0_0RCT_EXPORT_SHADOW_PROPERTY(placeholder, NSString) 74ABI47_0_0RCT_EXPORT_SHADOW_PROPERTY(onContentSizeChange, ABI47_0_0RCTBubblingEventBlock) 75 76ABI47_0_0RCT_CUSTOM_VIEW_PROPERTY(multiline, BOOL, UIView) 77{ 78 // No op. 79 // This View Manager doesn't use this prop but it must be exposed here via ViewConfig to enable Fabric component use it. 80} 81 82- (ABI47_0_0RCTShadowView *)shadowView 83{ 84 ABI47_0_0RCTBaseTextInputShadowView *shadowView = [[ABI47_0_0RCTBaseTextInputShadowView alloc] initWithBridge:self.bridge]; 85 shadowView.textAttributes.fontSizeMultiplier = [[[self.bridge 86 moduleForName:@"AccessibilityManager" 87 lazilyLoadIfNecessary:YES] valueForKey:@"multiplier"] floatValue]; 88 [_shadowViews addObject:shadowView]; 89 return shadowView; 90} 91 92- (void)setBridge:(ABI47_0_0RCTBridge *)bridge 93{ 94 [super setBridge:bridge]; 95 96 _shadowViews = [NSHashTable weakObjectsHashTable]; 97 98 [bridge.uiManager.observerCoordinator addObserver:self]; 99 100 [[NSNotificationCenter defaultCenter] addObserver:self 101 selector:@selector(handleDidUpdateMultiplierNotification) 102 name:@"ABI47_0_0RCTAccessibilityManagerDidUpdateMultiplierNotification" 103 object:[bridge moduleForName:@"AccessibilityManager" 104 lazilyLoadIfNecessary:YES]]; 105} 106 107ABI47_0_0RCT_EXPORT_METHOD(focus : (nonnull NSNumber *)viewTag) 108{ 109 [self.bridge.uiManager addUIBlock:^(ABI47_0_0RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) { 110 UIView *view = viewRegistry[viewTag]; 111 [view ABI47_0_0ReactFocus]; 112 }]; 113} 114 115ABI47_0_0RCT_EXPORT_METHOD(blur : (nonnull NSNumber *)viewTag) 116{ 117 [self.bridge.uiManager addUIBlock:^(ABI47_0_0RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) { 118 UIView *view = viewRegistry[viewTag]; 119 [view ABI47_0_0ReactBlur]; 120 }]; 121} 122 123ABI47_0_0RCT_EXPORT_METHOD(setTextAndSelection : (nonnull NSNumber *)viewTag 124 mostRecentEventCount : (NSInteger)mostRecentEventCount 125 value : (NSString *)value 126 start : (NSInteger)start 127 end : (NSInteger)end) 128{ 129 [self.bridge.uiManager addUIBlock:^(ABI47_0_0RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) { 130 ABI47_0_0RCTBaseTextInputView *view = (ABI47_0_0RCTBaseTextInputView *)viewRegistry[viewTag]; 131 NSInteger eventLag = view.nativeEventCount - mostRecentEventCount; 132 if (eventLag != 0) { 133 return; 134 } 135 ABI47_0_0RCTExecuteOnUIManagerQueue(^{ 136 ABI47_0_0RCTBaseTextInputShadowView *shadowView = (ABI47_0_0RCTBaseTextInputShadowView *)[self.bridge.uiManager shadowViewForABI47_0_0ReactTag:viewTag]; 137 if (value) { 138 [shadowView setText:value]; 139 } 140 [self.bridge.uiManager setNeedsLayout]; 141 ABI47_0_0RCTExecuteOnMainQueue(^{ 142 [view setSelectionStart:start selectionEnd:end]; 143 }); 144 }); 145 }]; 146} 147 148#pragma mark - ABI47_0_0RCTUIManagerObserver 149 150- (void)uiManagerWillPerformMounting:(__unused ABI47_0_0RCTUIManager *)uiManager 151{ 152 for (ABI47_0_0RCTBaseTextInputShadowView *shadowView in _shadowViews) { 153 [shadowView uiManagerWillPerformMounting]; 154 } 155} 156 157#pragma mark - Font Size Multiplier 158 159- (void)handleDidUpdateMultiplierNotification 160{ 161 CGFloat fontSizeMultiplier = [[[self.bridge moduleForName:@"AccessibilityManager"] 162 valueForKey:@"multiplier"] floatValue]; 163 164 NSHashTable<ABI47_0_0RCTBaseTextInputShadowView *> *shadowViews = _shadowViews; 165 ABI47_0_0RCTExecuteOnUIManagerQueue(^{ 166 for (ABI47_0_0RCTBaseTextInputShadowView *shadowView in shadowViews) { 167 shadowView.textAttributes.fontSizeMultiplier = fontSizeMultiplier; 168 [shadowView dirtyLayout]; 169 } 170 171 [self.bridge.uiManager setNeedsLayout]; 172 }); 173} 174 175@end 176