Skip to content

Commit 53b1261

Browse files
committed
feat: Add smartInsertDelete prop to TextInput component
1 parent e449706 commit 53b1261

12 files changed

Lines changed: 67 additions & 0 deletions

File tree

packages/react-native/Libraries/Components/TextInput/RCTTextInputViewConfig.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ const RCTTextInputViewConfig = {
156156
showSoftInputOnFocus: true,
157157
autoFocus: true,
158158
lineBreakStrategyIOS: true,
159+
smartInsertDelete: true,
159160
...ConditionallyIgnoredEventHandlers({
160161
onChange: true,
161162
onSelectionChange: true,

packages/react-native/Libraries/Components/TextInput/TextInput.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,14 @@ export interface TextInputIOSProps {
291291
| 'hangul-word'
292292
| 'push-out'
293293
| undefined;
294+
295+
/**
296+
* If `false`, the iOS system will not insert an extra space after a paste operation
297+
* neither delete one or two spaces after a cut or delete operation.
298+
*
299+
* The default value is `true`.
300+
*/
301+
smartInsertDelete?: boolean | undefined;
294302
}
295303

296304
/**

packages/react-native/Libraries/Components/TextInput/TextInput.flow.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,16 @@ type IOSProps = $ReadOnly<{|
295295
* @platform ios
296296
*/
297297
lineBreakStrategyIOS?: ?('none' | 'standard' | 'hangul-word' | 'push-out'),
298+
299+
/**
300+
* If `false`, the iOS system will not insert an extra space after a paste operation
301+
* neither delete one or two spaces after a cut or delete operation.
302+
*
303+
* The default value is `true`.
304+
*
305+
* @platform ios
306+
*/
307+
smartInsertDelete?: ?boolean,
298308
|}>;
299309

300310
type AndroidProps = $ReadOnly<{|

packages/react-native/Libraries/Components/TextInput/TextInput.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,16 @@ type IOSProps = $ReadOnly<{|
339339
* @platform ios
340340
*/
341341
lineBreakStrategyIOS?: ?('none' | 'standard' | 'hangul-word' | 'push-out'),
342+
343+
/**
344+
* If `false`, the iOS system will not insert an extra space after a paste operation
345+
* neither delete one or two spaces after a cut or delete operation.
346+
*
347+
* The default value is `true`.
348+
*
349+
* @platform ios
350+
*/
351+
smartInsertDelete?: ?boolean,
342352
|}>;
343353

344354
type AndroidProps = $ReadOnly<{|

packages/react-native/Libraries/Text/RCTConvert+Text.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ NS_ASSUME_NONNULL_BEGIN
1616
+ (UITextAutocorrectionType)UITextAutocorrectionType:(nullable id)json;
1717
+ (UITextSpellCheckingType)UITextSpellCheckingType:(nullable id)json;
1818
+ (RCTTextTransform)RCTTextTransform:(nullable id)json;
19+
+ (UITextSmartInsertDeleteType)UITextSmartInsertDeleteType:(nullable id)json;
1920

2021
@end
2122

packages/react-native/Libraries/Text/RCTConvert+Text.m

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,11 @@ + (UITextSpellCheckingType)UITextSpellCheckingType:(id)json
3434
RCTTextTransformUndefined,
3535
integerValue)
3636

37+
+ (UITextSmartInsertDeleteType)UITextSmartInsertDeleteType:(id)json
38+
{
39+
return json == nil ? UITextSmartInsertDeleteTypeDefault
40+
: [RCTConvert BOOL:json] ? UITextSmartInsertDeleteTypeYes
41+
: UITextSmartInsertDeleteTypeNo;
42+
}
43+
3744
@end

packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ @implementation RCTBaseTextInputViewManager {
4747
RCT_REMAP_VIEW_PROPERTY(clearButtonMode, backedTextInputView.clearButtonMode, UITextFieldViewMode)
4848
RCT_REMAP_VIEW_PROPERTY(scrollEnabled, backedTextInputView.scrollEnabled, BOOL)
4949
RCT_REMAP_VIEW_PROPERTY(secureTextEntry, backedTextInputView.secureTextEntry, BOOL)
50+
RCT_REMAP_VIEW_PROPERTY(smartInsertDelete, backedTextInputView.smartInsertDeleteType, UITextSmartInsertDeleteType)
5051
RCT_EXPORT_VIEW_PROPERTY(autoFocus, BOOL)
5152
RCT_EXPORT_VIEW_PROPERTY(submitBehavior, NSString)
5253
RCT_EXPORT_VIEW_PROPERTY(clearTextOnFocus, BOOL)

packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,11 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &
181181
_backedTextInputView.passwordRules = RCTUITextInputPasswordRulesFromString(newTextInputProps.traits.passwordRules);
182182
}
183183

184+
if (newTextInputProps.traits.smartInsertDelete != oldTextInputProps.traits.smartInsertDelete) {
185+
_backedTextInputView.smartInsertDeleteType =
186+
RCTUITextSmartInsertDeleteTypeFromOptionalBool(newTextInputProps.traits.smartInsertDelete);
187+
}
188+
184189
// Traits `blurOnSubmit`, `clearTextOnFocus`, and `selectTextOnFocus` were omitted intentionally here
185190
// because they are being checked on-demand.
186191

packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,6 @@ UITextContentType RCTUITextContentTypeFromString(std::string const &contentType)
3939

4040
UITextInputPasswordRules *RCTUITextInputPasswordRulesFromString(std::string const &passwordRules);
4141

42+
UITextSmartInsertDeleteType RCTUITextSmartInsertDeleteTypeFromOptionalBool(std::optional<bool> smartInsertDelete);
43+
4244
NS_ASSUME_NONNULL_END

packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.mm

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ void RCTCopyBackedTextInput(
4343
toTextInput.secureTextEntry = fromTextInput.secureTextEntry;
4444
toTextInput.keyboardType = fromTextInput.keyboardType;
4545
toTextInput.textContentType = fromTextInput.textContentType;
46+
toTextInput.smartInsertDeleteType = fromTextInput.smartInsertDeleteType;
4647

4748
toTextInput.passwordRules = fromTextInput.passwordRules;
4849

@@ -226,3 +227,9 @@ UITextContentType RCTUITextContentTypeFromString(std::string const &contentType)
226227
{
227228
return [UITextInputPasswordRules passwordRulesWithDescriptor:RCTNSStringFromStringNilIfEmpty(passwordRules)];
228229
}
230+
231+
UITextSmartInsertDeleteType RCTUITextSmartInsertDeleteTypeFromOptionalBool(std::optional<bool> smartInsertDelete)
232+
{
233+
return smartInsertDelete.has_value() ? (*smartInsertDelete ? UITextSmartInsertDeleteTypeYes : UITextSmartInsertDeleteTypeNo)
234+
: UITextSmartInsertDeleteTypeDefault;
235+
}

0 commit comments

Comments
 (0)