diff --git a/packages/core/core-types/index.ts b/packages/core/core-types/index.ts index 66bcae408a..760859bd7a 100644 --- a/packages/core/core-types/index.ts +++ b/packages/core/core-types/index.ts @@ -41,6 +41,12 @@ export namespace CoreTypes { export const email = 'email'; export const integer = 'integer'; } + export type AutofillType = 'username' | 'password' | 'none' | string; + export module AutofillType { + export const username = 'username'; + export const password = 'password'; + export const none = 'none'; + } export type ReturnKeyButtonType = 'done' | 'next' | 'go' | 'search' | 'send'; export module ReturnKeyType { diff --git a/packages/core/ui/editable-text-base/editable-text-base-common.ts b/packages/core/ui/editable-text-base/editable-text-base-common.ts index 1f4003d422..d34cf174a0 100644 --- a/packages/core/ui/editable-text-base/editable-text-base-common.ts +++ b/packages/core/ui/editable-text-base/editable-text-base-common.ts @@ -16,6 +16,7 @@ export abstract class EditableTextBase extends TextBase implements EditableTextB public returnKeyType: CoreTypes.ReturnKeyButtonType; public updateTextTrigger: CoreTypes.UpdateTextTriggerType; public autocapitalizationType: CoreTypes.AutocapitalizationInputType; + public autofillType: CoreTypes.AutofillType; public editable: boolean; public autocorrect: boolean; public hint: string; @@ -50,6 +51,11 @@ placeholderColorProperty.register(Style); const keyboardTypeConverter = makeParser(makeValidator(CoreTypes.KeyboardType.datetime, CoreTypes.KeyboardType.phone, CoreTypes.KeyboardType.number, CoreTypes.KeyboardType.url, CoreTypes.KeyboardType.email, CoreTypes.KeyboardType.integer), true); +const autofillTypeConverter = makeParser(makeValidator(CoreTypes.AutofillType.username, CoreTypes.AutofillType.password, CoreTypes.AutofillType.none), true); + +export const autofillTypeProperty = new Property({ name: 'autofillType', valueConverter: autofillTypeConverter }); +autofillTypeProperty.register(EditableTextBase); + export const keyboardTypeProperty = new Property({ name: 'keyboardType', valueConverter: keyboardTypeConverter }); keyboardTypeProperty.register(EditableTextBase); diff --git a/packages/core/ui/editable-text-base/index.android.ts b/packages/core/ui/editable-text-base/index.android.ts index 5dc8d24885..7501b1c3b2 100644 --- a/packages/core/ui/editable-text-base/index.android.ts +++ b/packages/core/ui/editable-text-base/index.android.ts @@ -1,10 +1,15 @@ -import { EditableTextBase as EditableTextBaseCommon, keyboardTypeProperty, returnKeyTypeProperty, editableProperty, autocapitalizationTypeProperty, autocorrectProperty, hintProperty, placeholderColorProperty, maxLengthProperty } from './editable-text-base-common'; +import { EditableTextBase as EditableTextBaseCommon, autofillTypeProperty, keyboardTypeProperty, returnKeyTypeProperty, editableProperty, autocapitalizationTypeProperty, autocorrectProperty, hintProperty, placeholderColorProperty, maxLengthProperty } from './editable-text-base-common'; import { textTransformProperty, textProperty, resetSymbol } from '../text-base'; import { Color } from '../../color'; import { ad } from '../../utils'; +import { CoreTypes } from '../../core-types'; +import { Device } from '../../platform'; +import lazy from '../../utils/lazy'; export * from './editable-text-base-common'; +const sdkVersion = lazy(() => parseInt(Device.sdkVersion)); + //https://github.com/NativeScript/NativeScript/issues/2942 export let dismissKeyboardTimeoutId: NodeJS.Timer; export let dismissKeyboardOwner: WeakRef; @@ -138,6 +143,8 @@ function initializeEditTextListeners(): void { EditTextListeners = EditTextListenersImpl; } +let apiLevel: number; + export abstract class EditableTextBase extends EditableTextBaseCommon { /* tslint:disable */ _dirtyTextAccumulator: string; @@ -157,6 +164,9 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { } public createNativeView() { + if (!apiLevel) { + apiLevel = sdkVersion(); + } return new android.widget.EditText(this._context); } @@ -293,6 +303,50 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { this._setInputType(newInputType); } + [autofillTypeProperty.setNative](value: CoreTypes.AutofillType) { + if (apiLevel < 26) { + return; + } + let newOptions; + switch (value) { + case 'phone': + newOptions = 'phone'; // android.view.View.AUTOFILL_HINT_PHONE + break; + case 'postalCode': + newOptions = 'postalCode'; // android.view.View.AUTOFILL_HINT_POSTAL_CODE + break; + case 'creditCardNumber': + newOptions = 'creditCardNumber'; // android.view.View.AUTOFILL_HINT_CREDIT_CARD_NUMBER + break; + case 'email': + newOptions = 'emailAddress'; // android.view.View.AUTOFILL_HINT_EMAIL_ADDRESS + break; + case 'name': + newOptions = 'name'; // android.view.View.AUTOFILL_HINT_NAME + break; + case 'username': + newOptions = 'username'; // android.view.View.AUTOFILL_HINT_USERNAME + break; + case 'password': + newOptions = 'password'; // android.view.View.AUTOFILL_HINT_PASSWORD + break; + case 'none': + newOptions = null; + break; + default: { + newOptions = value; + break; + } + } + if (newOptions) { + const array = Array.create(java.lang.String, 1); + array[0] = newOptions; + this.nativeTextViewProtected.setAutofillHints(array); + } else { + this.nativeTextViewProtected.setAutofillHints(null); + } + } + [returnKeyTypeProperty.getDefault](): 'done' | 'next' | 'go' | 'search' | 'send' | string { const ime = this.nativeTextViewProtected.getImeOptions(); switch (ime) { diff --git a/packages/core/ui/editable-text-base/index.d.ts b/packages/core/ui/editable-text-base/index.d.ts index 9e3fafbd00..6e17dd449b 100644 --- a/packages/core/ui/editable-text-base/index.d.ts +++ b/packages/core/ui/editable-text-base/index.d.ts @@ -33,6 +33,11 @@ export class EditableTextBase extends TextBase { */ autocapitalizationType: CoreTypes.AutocapitalizationInputType; + /** + * Gets or sets the autofill type. + */ + autofillType: CoreTypes.AutofillType; + /** * Gets or sets whether the instance is editable. */ diff --git a/packages/core/ui/editable-text-base/index.ios.ts b/packages/core/ui/editable-text-base/index.ios.ts index 6af98a69bb..031de38a03 100644 --- a/packages/core/ui/editable-text-base/index.ios.ts +++ b/packages/core/ui/editable-text-base/index.ios.ts @@ -1,5 +1,6 @@ -import { EditableTextBase as EditableTextBaseCommon, keyboardTypeProperty, returnKeyTypeProperty, autocapitalizationTypeProperty, autocorrectProperty } from './editable-text-base-common'; +import { EditableTextBase as EditableTextBaseCommon, autofillTypeProperty, keyboardTypeProperty, returnKeyTypeProperty, autocapitalizationTypeProperty, autocorrectProperty } from './editable-text-base-common'; import { FormattedString } from '../text-base/formatted-string'; +import { CoreTypes } from '../../core-types'; export * from './editable-text-base-common'; @@ -71,6 +72,39 @@ export abstract class EditableTextBase extends EditableTextBaseCommon { this.nativeTextViewProtected.keyboardType = newKeyboardType; } + [autofillTypeProperty.setNative](value: CoreTypes.AutofillType) { + let newTextContentType: string; + switch (value) { + case 'phone': + newTextContentType = UITextContentTypeTelephoneNumber; + break; + case 'postalCode': + newTextContentType = UITextContentTypePostalCode; + break; + case 'creditCardNumber': + newTextContentType = UITextContentTypeCreditCardNumber; + break; + case 'email': + newTextContentType = UITextContentTypeEmailAddress; + break; + case 'name': + newTextContentType = UITextContentTypeName; + break; + case 'username': + newTextContentType = UITextContentTypeUsername; + break; + case 'password': + newTextContentType = UITextContentTypePassword; + break; + case 'none': + newTextContentType = null; + default: + newTextContentType = value; + break; + } + + this.nativeTextViewProtected.textContentType = newTextContentType; + } [returnKeyTypeProperty.getDefault](): 'done' | 'next' | 'go' | 'search' | 'send' | string { const returnKeyType = this.nativeTextViewProtected.returnKeyType;