mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Add smartInsertDelete prop to TextInput component (#36111)
Summary: This PR add support to configure the `smartInsertDeleteType` property in iOS inputs [as described here](https://developer.apple.com/documentation/uikit/uitextinputtraits/2865828-smartinsertdeletetype), making possible toggle this autoformatting behavior. PR for the docs update: https://github.com/facebook/react-native-website/pull/3560 ## Changelog: [IOS] [ADDED] - Add `smartInsertDelete` prop to `TextInput` component Pull Request resolved: https://github.com/facebook/react-native/pull/36111 Test Plan: * Added an example in the RNTester app to test this behavior in iOS. * If the `smartInsertDelete` prop is `true` or `undefined`, the system will use the default autoformatting behavior. * If the `smartInsertDelete` prop is `false`, the system will disable the autoformatting behavior. https://user-images.githubusercontent.com/20051562/217862828-70c20344-d687-4824-8f5d-d591eff856ef.mp4 Reviewed By: javache Differential Revision: D46546277 Pulled By: NickGerleman fbshipit-source-id: 3172b14fb196876d9ee0030186540608204b96de
This commit is contained in:
committed by
Facebook GitHub Bot
parent
09e152e004
commit
6b62f12ce9
+1
@@ -156,6 +156,7 @@ const RCTTextInputViewConfig = {
|
||||
showSoftInputOnFocus: true,
|
||||
autoFocus: true,
|
||||
lineBreakStrategyIOS: true,
|
||||
smartInsertDelete: true,
|
||||
...ConditionallyIgnoredEventHandlers({
|
||||
onChange: true,
|
||||
onSelectionChange: true,
|
||||
|
||||
@@ -291,6 +291,14 @@ export interface TextInputIOSProps {
|
||||
| 'hangul-word'
|
||||
| 'push-out'
|
||||
| undefined;
|
||||
|
||||
/**
|
||||
* If `false`, the iOS system will not insert an extra space after a paste operation
|
||||
* neither delete one or two spaces after a cut or delete operation.
|
||||
*
|
||||
* The default value is `true`.
|
||||
*/
|
||||
smartInsertDelete?: boolean | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -295,6 +295,16 @@ type IOSProps = $ReadOnly<{|
|
||||
* @platform ios
|
||||
*/
|
||||
lineBreakStrategyIOS?: ?('none' | 'standard' | 'hangul-word' | 'push-out'),
|
||||
|
||||
/**
|
||||
* If `false`, the iOS system will not insert an extra space after a paste operation
|
||||
* neither delete one or two spaces after a cut or delete operation.
|
||||
*
|
||||
* The default value is `true`.
|
||||
*
|
||||
* @platform ios
|
||||
*/
|
||||
smartInsertDelete?: ?boolean,
|
||||
|}>;
|
||||
|
||||
type AndroidProps = $ReadOnly<{|
|
||||
|
||||
@@ -339,6 +339,16 @@ type IOSProps = $ReadOnly<{|
|
||||
* @platform ios
|
||||
*/
|
||||
lineBreakStrategyIOS?: ?('none' | 'standard' | 'hangul-word' | 'push-out'),
|
||||
|
||||
/**
|
||||
* If `false`, the iOS system will not insert an extra space after a paste operation
|
||||
* neither delete one or two spaces after a cut or delete operation.
|
||||
*
|
||||
* The default value is `true`.
|
||||
*
|
||||
* @platform ios
|
||||
*/
|
||||
smartInsertDelete?: ?boolean,
|
||||
|}>;
|
||||
|
||||
type AndroidProps = $ReadOnly<{|
|
||||
|
||||
@@ -16,6 +16,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
+ (UITextAutocorrectionType)UITextAutocorrectionType:(nullable id)json;
|
||||
+ (UITextSpellCheckingType)UITextSpellCheckingType:(nullable id)json;
|
||||
+ (RCTTextTransform)RCTTextTransform:(nullable id)json;
|
||||
+ (UITextSmartInsertDeleteType)UITextSmartInsertDeleteType:(nullable id)json;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -34,4 +34,11 @@ RCT_ENUM_CONVERTER(
|
||||
RCTTextTransformUndefined,
|
||||
integerValue)
|
||||
|
||||
+ (UITextSmartInsertDeleteType)UITextSmartInsertDeleteType:(id)json
|
||||
{
|
||||
return json == nil ? UITextSmartInsertDeleteTypeDefault
|
||||
: [RCTConvert BOOL:json] ? UITextSmartInsertDeleteTypeYes
|
||||
: UITextSmartInsertDeleteTypeNo;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -47,6 +47,7 @@ RCT_REMAP_VIEW_PROPERTY(caretHidden, backedTextInputView.caretHidden, BOOL)
|
||||
RCT_REMAP_VIEW_PROPERTY(clearButtonMode, backedTextInputView.clearButtonMode, UITextFieldViewMode)
|
||||
RCT_REMAP_VIEW_PROPERTY(scrollEnabled, backedTextInputView.scrollEnabled, BOOL)
|
||||
RCT_REMAP_VIEW_PROPERTY(secureTextEntry, backedTextInputView.secureTextEntry, BOOL)
|
||||
RCT_REMAP_VIEW_PROPERTY(smartInsertDelete, backedTextInputView.smartInsertDeleteType, UITextSmartInsertDeleteType)
|
||||
RCT_EXPORT_VIEW_PROPERTY(autoFocus, BOOL)
|
||||
RCT_EXPORT_VIEW_PROPERTY(submitBehavior, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(clearTextOnFocus, BOOL)
|
||||
|
||||
+7
@@ -181,6 +181,13 @@ using namespace facebook::react;
|
||||
_backedTextInputView.passwordRules = RCTUITextInputPasswordRulesFromString(newTextInputProps.traits.passwordRules);
|
||||
}
|
||||
|
||||
if (newTextInputProps.traits.smartInsertDelete != oldTextInputProps.traits.smartInsertDelete) {
|
||||
if (@available(iOS 11.0, *)) {
|
||||
_backedTextInputView.smartInsertDeleteType =
|
||||
RCTUITextSmartInsertDeleteTypeFromOptionalBool(newTextInputProps.traits.smartInsertDelete);
|
||||
}
|
||||
}
|
||||
|
||||
// Traits `blurOnSubmit`, `clearTextOnFocus`, and `selectTextOnFocus` were omitted intentionally here
|
||||
// because they are being checked on-demand.
|
||||
|
||||
|
||||
+2
@@ -39,4 +39,6 @@ UITextContentType RCTUITextContentTypeFromString(std::string const &contentType)
|
||||
|
||||
UITextInputPasswordRules *RCTUITextInputPasswordRulesFromString(std::string const &passwordRules);
|
||||
|
||||
UITextSmartInsertDeleteType RCTUITextSmartInsertDeleteTypeFromOptionalBool(std::optional<bool> smartInsertDelete);
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
+11
@@ -44,6 +44,10 @@ void RCTCopyBackedTextInput(
|
||||
toTextInput.keyboardType = fromTextInput.keyboardType;
|
||||
toTextInput.textContentType = fromTextInput.textContentType;
|
||||
|
||||
if (@available(iOS 11.0, *)) {
|
||||
toTextInput.smartInsertDeleteType = fromTextInput.smartInsertDeleteType;
|
||||
}
|
||||
|
||||
toTextInput.passwordRules = fromTextInput.passwordRules;
|
||||
|
||||
[toTextInput setSelectedTextRange:fromTextInput.selectedTextRange notifyDelegate:NO];
|
||||
@@ -226,3 +230,10 @@ UITextInputPasswordRules *RCTUITextInputPasswordRulesFromString(std::string cons
|
||||
{
|
||||
return [UITextInputPasswordRules passwordRulesWithDescriptor:RCTNSStringFromStringNilIfEmpty(passwordRules)];
|
||||
}
|
||||
|
||||
UITextSmartInsertDeleteType RCTUITextSmartInsertDeleteTypeFromOptionalBool(std::optional<bool> smartInsertDelete)
|
||||
{
|
||||
return smartInsertDelete.has_value()
|
||||
? (*smartInsertDelete ? UITextSmartInsertDeleteTypeYes : UITextSmartInsertDeleteTypeNo)
|
||||
: UITextSmartInsertDeleteTypeDefault;
|
||||
}
|
||||
|
||||
+9
@@ -222,6 +222,15 @@ class TextInputTraits final {
|
||||
* Default value: `<empty string>` (no rules).
|
||||
*/
|
||||
std::string passwordRules{};
|
||||
|
||||
/*
|
||||
* If `false`, the iOS system will not insert an extra space after a paste
|
||||
* operation neither delete one or two spaces after a cut or delete operation.
|
||||
* iOS-only (inherently iOS-specific)
|
||||
* Can be empty (`null` in JavaScript) which means `default`.
|
||||
* Default value: `empty` (`null`).
|
||||
*/
|
||||
std::optional<bool> smartInsertDelete{};
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
+6
@@ -141,6 +141,12 @@ static TextInputTraits convertRawProp(
|
||||
"passwordRules",
|
||||
sourceTraits.passwordRules,
|
||||
defaultTraits.passwordRules);
|
||||
traits.smartInsertDelete = convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"smartInsertDelete",
|
||||
sourceTraits.smartInsertDelete,
|
||||
defaultTraits.smartInsertDelete);
|
||||
|
||||
return traits;
|
||||
}
|
||||
|
||||
@@ -906,4 +906,23 @@ exports.examples = ([
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'iOS autoformatting behaviors',
|
||||
render: function (): React.Node {
|
||||
return (
|
||||
<View>
|
||||
<WithLabel label="smartInsertDelete: true | undefined">
|
||||
<TextInput style={styles.default} defaultValue="CopyAndPaste" />
|
||||
</WithLabel>
|
||||
<WithLabel label="smartInsertDelete: false">
|
||||
<TextInput
|
||||
smartInsertDelete={false}
|
||||
style={styles.default}
|
||||
defaultValue="CopyAndPaste"
|
||||
/>
|
||||
</WithLabel>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
},
|
||||
]: Array<RNTesterModuleExample>);
|
||||
|
||||
Reference in New Issue
Block a user