CommunityToolkit / CommunityToolkit/Maui
[Proposal] Autofill Hints
- Dominant language
- C#
- Stars
- 2.7k
- Forks
- 500
- Avg merge
- 2d 14h
- Merged PRs (30d)
- 7
Description
# Autofill Hints
* [x] Proposed
* [x] Prototype: Not Started
* [x] Implementation: Xamarin Version Exists and can be ported over.
* [x] iOS Support
* [x] Android Support
* [ ] macOS Support (currently not working, requires fix in MAUI)
* [ ] Windows Support
* [ ] Unit Tests: Not Started
* [ ] Sample: Not Started
* [ ] Documentation: Not Started
## Summary
[summary]: #summary
I would like to request to add autofill to MCT. Autofill is common in HTML, where the browsers remembers a user's details and fills them in. This is also possible on the OS level in Android, iOS and (I think also) macOS.
## Motivation
[motivation]: #motivation
It's nice for users to log in with a tap on their screen and it makes it easier to sign up for within an app.
## Detailed Design
[design]: #detailed-design
I've included the implementation that I have in Xamarin Forms.
The namespaces have already been renamed.
This is the API class.
```csharp
using System;
using Xamarin.Forms; // should become Miscrosoft.Maui
namespace CommunityToolkit.Maui.Effects
{
public class AutofillEffect : RoutingEffect {
public AutofillContentType Type { get; set; }
public AutofillEffect() : base(nameof(AutofillEffect)) {}
}
// TODO extend with all possibilities
public enum AutofillContentType {
None,
Username,
Password,
NewPassword,
Email,
FirstName,
Phone
}
}
```
The Android class:
```csharp
using System;
using System.Linq;
using Android.OS;
using Android.Views;
using Android.Widget;
using CommunityToolkit.Maui.Effects;
using CommunityToolkit.Maui.Android.Effects;
using Xamarin.Forms.Platform.Android;
[assembly: Xamarin.Forms.ResolutionGroupName("CommunityToolkit")]
[assembly: Xamarin.Forms.ExportEffect(typeof(AndroidAutofillEffect), "AutofillEffect")]
namespace CommunityToolkit.Maui.Android.Effects {
public class AndroidAutofillEffect : PlatformEffect {
protected override void OnAttached() {
var effect = (AutofillEffect) Element.Effects.FirstOrDefault(e => e is AutofillEffect);
if (effect != null
&& Build.VERSION.SdkInt >= BuildVersionCodes.O
&& Control is EditText editText) {
switch (effect.Type) {
case AutofillContentType.Username:
editText.ImportantForAutofill = ImportantForAutofill.Yes;
editText.SetAutofillHints(View.AutofillHintUsername);
break;
case AutofillContentType.Password:
editText.ImportantForAutofill = ImportantForAutofill.Yes;
editText.SetAutofillHints(View.AutofillHintPassword);
break;
case AutofillContentType.Email:
editText.ImportantForAutofill = ImportantForAutofill.Yes;
editText.SetAutofillHints(View.AutofillHintEmailAddress);
break;
case AutofillContentType.FirstName:
editText.ImportantForAutofill = ImportantForAutofill.Yes;
editText.SetAutofillHints(View.AutofillHintName); // Not implemented
break;
case AutofillContentType.Phone:
editText.ImportantForAutofill = ImportantForAutofill.Yes;
editText.SetAutofillHints(View.AutofillHintPhone);
break;
default:
editText.ImportantForAutofill = ImportantForAutofill.Auto;
editText.SetAutofillHints(autofillHints: null);
break;
}
}
}
protected override void OnDetached() {
if (Build.VERSION.SdkInt >= BuildVersionCodes.O
&& Control is EditText editText) {
editText.ImportantForAutofill = ImportantForAutofill.Auto;
editText.SetAutofillHints(autofillHints: null);
}
}
}
}
```
The iOS (and similarly macOS) class:
```csharp
using System.Linq;
using Foundation;
using UIKit;
using CommunityToolkit.Maui.Effects;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportEffect(typeof(AppleAutofillEffect), "AutofillEffect")]
public class AppleAutofillEffect : PlatformEffect {
protected override void OnAttached() {
var effect = (AutofillEffect)Element.Effects
.FirstOrDefault(e => e is AutofillEffect);
if (effect != null
&& UIDevice.CurrentDevice.CheckSystemVersion(11, 0)
&& Control is UITextField textField) {
switch (effect.Type) {
case AutofillContentType.Username:
textField.TextContentType = UITextContentType.Username;
break;
case AutofillContentType.Password:
textField.TextContentType = UITextContentType.Password;
break;
case AutofillContentType.NewPassword:
textField.TextContentType = UITextContentType.NewPassword;
break;
case AutofillContentType.Email:
textField.TextContentType = UITextContentType.EmailAddress;
break;
case AutofillContentType.FirstName:
textField.TextContentType = UITextContentType.GivenName;
break;
case AutofillContentType.Phone:
textField.TextContentType = UITextContentType.TelephoneNumber;
break;
default:
textField.TextContentType = NSString.Empty;
break;
}
}
}
protected override void OnDetached() {
if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0)
&& Control is UITextField textField) {
textField.TextContentType = NSString.Empty;
}
}
}
```
## Usage Syntax
[usage]: #usage-syntax
### XAML Usage
```xml
< Entry.Effects Margin="15,5" x:Name="EmailEntry"
Keyboard="Email" Text="{Binding Email}"
ReturnType="Next"
Placeholder="{x:Static lang:Lang.Email}">
```
## Drawbacks
[drawbacks]: #drawbacks
Currently the Android C# wrapper has limited support.
The View class doesn't have all strings (e.g. AUTOFILL_HINT_PERSON_NAME_GIVEN), but they can be added manually.
https://developer.android.com/guide/topics/text/autofill-optimize
## Alternatives
[alternatives]: #alternatives
N/A
## Unresolved Questions
[unresolved]: #unresolved-questions
What is the 'correct' way of implementing this in MAUI? (now it's XF Compat)
Does Windows have something similar to Autofill?
Contributor guide
Research direction
Start with the provided Xamarin.Forms AutofillEffect API and the Android and iOS platform-effect snippets, then review how they should be adapted for .NET MAUI. The work is complete only when the supported platforms, unit tests, sample, and documentation listed in the proposal are addressed, including the unresolved macOS and Windows questions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- desktop-dev, mobile-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100