Skip to content

[Android] Implemented material3 support for Editor#33478

Merged
jfversluis merged 6 commits intodotnet:inflight/currentfrom
SyedAbdulAzeemSF4852:material3-editor
Feb 28, 2026
Merged

[Android] Implemented material3 support for Editor#33478
jfversluis merged 6 commits intodotnet:inflight/currentfrom
SyedAbdulAzeemSF4852:material3-editor

Conversation

@SyedAbdulAzeemSF4852
Copy link
Copy Markdown
Contributor

@SyedAbdulAzeemSF4852 SyedAbdulAzeemSF4852 commented Jan 12, 2026

Description of Change

  • This PR introduces Material Design 3 support for the Editor control on Android.

New classes (internal, TODO: make public in .NET 11):

  • EditorHandler2 (EditorHandler2.Android.cs): A new handler extending ViewHandler<IEditor, MauiMaterialEditText> that wraps MauiMaterialEditText (a TextInputEditText-based view) instead of the standard AppCompatEditText.

  • Implements full property/command mapper parity with EditorHandler, including DataFlowDirection tracking to distinguish platform-initiated vs MAUI-initiated text updates. Subscribes to TextChanged, FocusChange, and SelectionChanged events; calls VirtualView.Completed() on focus loss; syncs CursorPosition/SelectionLength on selection changes. Overrides PlatformArrange with PrepareForTextViewArrange.

  • MauiMaterialEditText (MauiMaterialEditText.cs): Extends TextInputEditText (from the Material library) to expose a SelectionChanged event via override of OnSelectionChanged, enabling cursor/selection position tracking by the handler. Wraps the context with MauiMaterialContextThemeWrapper to apply the Material 3 theme.

Handler registration (AppHostBuilderExtensions.cs):

  • On Android, when RuntimeFeature.IsMaterial3Enabled is true, EditorHandler2 is registered for Editor; otherwise the standard EditorHandler is used.
  • On all other platforms, the standard EditorHandler is used (unchanged).

Mapper setup (Editor.Mapper.cs, Editor.Android.cs):

  • When Material 3 is enabled on Android, additional mappings are registered on EditorHandler2.Mapper and EditorHandler2.CommandMapper:

  • ReplaceMapping for Text and TextTransform → platform-overloaded MapText (handles DataFlowDirection)

  • AppendToMapping for IsFocused → InputView.MapIsFocused

  • PrependToMapping for Focus → InputView.MapFocus

Issues Fixed

Fixes #33476

Output

Material2 Material3

@dotnet-policy-service dotnet-policy-service bot added community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration labels Jan 12, 2026
@sheiksyedm sheiksyedm marked this pull request as ready for review January 12, 2026 13:28
Copilot AI review requested due to automatic review settings January 12, 2026 13:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request implements Material Design 3 support for the Editor control on Android by introducing a new MaterialEditorHandler and MauiMaterialEditText control. The implementation enables Material 3 styling for editors when the Material 3 runtime feature is enabled, providing a more modern and consistent UI experience.

Changes:

  • Added MauiMaterialEditText class that extends TextInputEditText to support Material 3 styling with selection change events
  • Implemented MaterialEditorHandler with full property and command mapping support for Material 3 editors
  • Updated handler registration logic to conditionally use MaterialEditorHandler when Material 3 is enabled
  • Extended property mapping to support the new Material 3 handler for text-related properties

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/Core/src/Platform/Android/Material3Controls/MauiMaterialEditText.cs New Material 3 EditText control with selection change event support
src/Core/src/Handlers/Editor/MaterialEditorHandler.Android.cs New handler implementing Material 3 styling and behavior for Editor control
src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs Conditional handler registration based on Material 3 feature flag
src/Controls/src/Core/Editor/Editor.Mapper.cs Property mapping registration for Material 3 handler
src/Controls/src/Core/Editor/Editor.Android.cs Material 3-specific MapText implementation with data flow handling

@rmarinho
Copy link
Copy Markdown
Member

rmarinho commented Feb 18, 2026

🤖 AI Summary

📊 Expand Full Review
🔍 Pre-Flight — Context & Validation
📝 Review SessionAdded TODO comment and refactored class and file names · f895a14

Issue: #33476 - Implement Material3 Support for Editor
PR: #33478 - [Android] Implemented material3 support for Editor
Author: SyedAbdulAzeemSF4852 (Syncfusion partner/community)
Platforms Affected: Android only
Files Changed: 5 implementation files, 0 test files

Issue Summary

When the UseMaterial3 MSBuild property is enabled, the Editor control should adopt the Material Design 3 visual design system on Android. The current implementation does not fully reflect Material 3 behavior (updated colors, text field appearance, state behaviors).

PR Approach

The PR introduces:

  1. EditorHandler2 - a new internal Material3 Android handler for Editor (src/Core/src/Handlers/Editor/EditorHandler2.Android.cs)
  2. MauiMaterialEditText - a new class extending TextInputEditText with selection change events (src/Core/src/Platform/Android/Material3Controls/MauiMaterialEditText.cs)
  3. Conditional handler registration in AppHostBuilderExtensions.cs - uses EditorHandler2 when Material3 is enabled, EditorHandler otherwise
  4. Property mapper updates in Editor.Mapper.cs - adds Text, TextTransform, IsFocused, Focus mappings for EditorHandler2
  5. MapText overload in Editor.Android.cs for EditorHandler2 with DataFlowDirection support

PR Discussion Summary

Copilot automated review identified:

Issue Reviewer Says Status
MauiMaterialEditText constructor inconsistency Constructors with attrs params don't call MauiMaterialContextThemeWrapper.Create(context) unlike primary inconsistent with MauiMaterialButton REAL ISSUE pattern
Duplicate handler registration code AppHostBuilderExtensions.cs if/else could be simplified with STYLE ternary
Missing Focus/IsFocused mappings Suggested these ARE present in the diff ALREADY DONE
Missing tests No test coverage for Material3-specific REAL ISSUE behavior

Key Technical Observations

  • Naming inconsistency: PR description calls it MaterialEditorHandler but actual class is EditorHandler2 (marked // TODO: Material3 - make it public in .net 11)
  • Pattern: Mirrors the Material3 Button handler approach (compare MauiMaterialButton.cs)
  • MauiMaterialEditText ctor bug: The MauiMaterialButton wraps context in ALL constructors with MauiMaterialContextThemeWrapper.Create(context). MauiMaterialEditText only wraps the primary (Context context) the (Context, IAttributeSet) and (Context, IAttributeSet, int) ctors pass raw context, meaning Material3 theme won't apply when inflated from XML or via those ctors.ctor
  • Missing newline at end of file: Both new files lack trailing newline

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #33478 New EditorHandler2 + MauiMaterialEditText, conditional PENDING (Gate) 5 files Original no tests included PR registration

🚦 Gate — Test Verification
📝 Review SessionAdded TODO comment and refactored class and file names · f895a14

** FAILEDResult:**
Platform: android
Mode: N/ No tests existA

Finding

No test files exist for this PR or issue #33476. The PR does not include any:

  • UI test pages in TestCases.HostApp/Issues/
  • NUnit test implementations in TestCases.Shared.Tests/Tests/Issues/
  • Device test extensions in Core/tests/DeviceTests/

This is a new feature (Material3 Editor handler) and the PR ships without any automated test coverage.

Action Required

Tests must be added before Gate can pass. The write-tests-agent skill can help create them.

Suggested test coverage:

  • Verify EditorHandler2 is registered when Material3 is enabled on Android
  • Verify EditorHandler is registered when Material3 is disabled
  • Verify basic Editor property mapping works correctly with the Material3 handler (Text, Placeholder, TextColor, etc.)

🔧 Fix — Analysis & Comparison
📝 Review SessionAdded TODO comment and refactored class and file names · f895a14

Skipped: FAILED (no tests Phase 3 requires Gate to pass first.exist) Gate

No try-fix attempts were made.

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #33478 New EditorHandler2 + MauiMaterialEditText, conditional NOT VERIFIED (no tests) 5 files Gate could not run registration

Exhausted: N/A (skipped)
Selected Fix: N/ Gate did not passA


📋 Report — Final Recommendation
📝 Review SessionAdded TODO comment and refactored class and file names · f895a14

Final Recommendation: REQUEST CHANGES##

Summary

PR #33478 implements Material Design 3 support for the Android Editor control by introducing EditorHandler2 (a new internal handler) and MauiMaterialEditText (extending TextInputEditText). The implementation uses conditional handler registration based on RuntimeFeature.IsMaterial3Enabled. The overall approach is correct and follows existing Material3 patterns in the codebase.

However, there are blocking issues that must be addressed before merge:

  1. Gate No tests were included with this PRFailed
  2. Bug in MauiMaterialEditText Material3 theme not applied consistentlyconstructors

Root Cause (of Issue #33476)

The Editor control on Android used EditorHandler/MauiEditText which has no Material3 styling. When UseMaterial3 is enabled, a dedicated handler backed by TextInputEditText (Material3 styled) is needed.


The PR includes zero test coverage. No UI tests, no device tests for the new EditorHandler2.###


Code Review Findings

File: src/Core/src/Platform/Android/Material3Controls/MauiMaterialEditText.cs####

The primary constructor wraps the context with MauiMaterialContextThemeWrapper.Create(context), but the additional constructors do NOT:

//  Primary  correctctor 
public MauiMaterialEditText(Context context) : base(MauiMaterialContextThemeWrapper.Create(context))

 Missing theme wrapper// 
public MauiMaterialEditText(Context context, IAttributeSet? attrs) : base(context, attrs)
public MauiMaterialEditText(Context context, IAttributeSet? attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)

This is inconsistent with the established pattern in MauiMaterialButton:

//  MauiMaterialButton pattern (correct)
public MauiMaterialButton(Context context, IAttributeSet? attrs) : base(MauiMaterialContextThemeWrapper.Create(context), attrs)
public MauiMaterialButton(Context context, IAttributeSet? attrs, int defStyleAttr) : base(MauiMaterialContextThemeWrapper.Create(context), attrs, defStyleAttr)

Fix: Apply MauiMaterialContextThemeWrapper.Create(context) in all constructors.

No automated tests validate that EditorHandler2 is properly registered and functional when Material3 is enabled. This is required for Gate to pass.####

File: src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs####

The if/else block can be simplified:

// Current: verbose if/else
if (RuntimeFeature.IsMaterial3Enabled)
    handlersCollection.AddHandler<Editor, EditorHandler2>();
else
    handlersCollection.AddHandler<Editor, EditorHandler>();

// Suggested: single line
handlersCollection.AddHandler(typeof(Editor),
    RuntimeFeature.IsMaterial3Enabled ? typeof(EditorHandler2) : typeof(EditorHandler));

PR description references MaterialEditorHandler but actual code uses EditorHandler2. The TODO comments say "make it public in .net 11" which clarifies the intent. PR description should be updated to match the actual class names.####

Both EditorHandler2.Android.cs and MauiMaterialEditText.cs are missing a trailing newline (\ No newline at end of file).####


PR Title & Description Review

Title: [Android] Implemented material3 support for Editor

  • "Implemented" should be imperative: "Add Material3 support for Editor"
  • Recommended: [Android] Editor: Add Material3 handler support-

Description:
Missing NOTE block (required by contributing guidelines)-
References actual class isEditorHandler2MaterialEditorHandler -

  • Has "Description of Change" and "Issues Fixed" sections
  • Includes before/after screenshots

Recommended additions:

  1. Add NOTE block at the top
  2. Update class name references to EditorHandler2
  3. Clarify that the handler is currently internal (to be made public in .NET 11)

Required Changes (must-fix before merge)

  1. Fix MauiMaterialEditText constructors to consistently call MauiMaterialContextThemeWrapper.Create(context) in ALL constructors
  2. Add tests (device tests validating Material3 handler registration and basic Editor properties)

Suggested Changes (nice-to-have)

  1. Simplify handler registration to a single ternary line
  2. Add NOTE block to PR description
  3. Fix MaterialEditorHandler references to EditorHandler2 in PR description
  4. Add trailing newlines to new files

📋 Expand PR Finalization Review
Title: ✅ Good

Current: [Android] Implemented material3 support for Editor

Description: ⚠️ Needs Update
  • "Implemented" is past tense; MAUI convention uses imperative/present tense
  • "material3" should be capitalized as "Material 3"
  • Missing component "support" is vague; the actual change is a new handler + platform controlclarity
    Missing Elements:

**
Missing NOTE block (required per MAUI contribution guidelines)-
Does not mention that EditorHandler2 and MauiMaterialEditText are internal with TODO to make public in .NET 11-
Does not mention the DataFlowDirection pattern used to track text-update origin-

Recommendation: Update description to fix class names and add the NOTE block. A full recommended description is provided in recommended-description.md.


Phase 2: Code Review

See code-review.md for detailed findings.

Summary:

      • Core property mapping, text DataFlowDirection tracking, focus/keyboard handling, and lifecycle management look correct

Overall Verdict

The PR implements the intended feature correctly but has:

  1. Significant description wrong handler class name throughout (MaterialEditorHandler vs actual EditorHandler2)inaccuracy
  2. Fragile event SelectionChanged subscribed in SetVirtualView instead of ConnectHandler/DisconnectHandlersubscription
  3. Missing NOTE block in description

These should be addressed before merge.

✨ Suggested PR Description

[!NOTE]
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Description of Change

This PR introduces Material Design 3 support for the Editor control on Android.

New classes (internal, TODO: make public in .NET 11):

  • EditorHandler2 (src/Core/src/Handlers/Editor/EditorHandler2.Android. A new handler class for Android that wraps MauiMaterialEditText(aTextInputEditText-based view) instead of the standard AppCompatEditText. Implements full property/command mapper parity with EditorHandler, including DataFlowDirection tracking to distinguish platform-initiated vs MAUI-initiated text updates.cs)
  • MauiMaterialEditText (src/Core/src/Platform/Android/Material3Controls/MauiMaterialEditText. Extends TextInputEditText(from the Material library) to expose aSelectionChangedevent via override ofOnSelectionChanged, enabling cursor/selection position tracking by the handler.cs)

Handler registration (AppHostBuilderExtensions.cs):

  • On Android, when RuntimeFeature.IsMaterial3Enabled is true, EditorHandler2 is registered for Editor; otherwise the standard EditorHandler is used.
  • On all other platforms, the standard EditorHandler is used (unchanged).

Mapper setup (Editor.Mapper.cs, Editor.Android.cs):

  • When Material 3 is enabled on Android, additional mappings are registered on EditorHandler2.Mapper and EditorHandler2.CommandMapper:
    platform-overloaded MapText (handles DataFlowDirection)
    InputView.MapIsFocused
    InputView.MapFocus

Issues Fixed

Fixes #33476

Output

Material2 Material3
Code Review: ✅ Passed

Code PR #33478Review

Files reviewed:

  • src/Core/src/Handlers/Editor/EditorHandler2.Android.cs (new, 221 lines)
  • src/Core/src/Platform/Android/Material3Controls/MauiMaterialEditText.cs (new, 36 lines)
  • src/Controls/src/Core/Editor/Editor.Android.cs (modified)
  • src/Controls/src/Core/Editor/Editor.Mapper.cs (modified)
  • src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs (modified)

SelectionChanged subscription should be in ConnectHandler/DisconnectHandler, not SetVirtualView

File: src/Core/src/Handlers/Editor/EditorHandler2.Android.cs

Problem:

public override void SetVirtualView(IView view)
{
    base.SetVirtualView(view);

    if (!_set)
    {
        PlatformView.SelectionChanged += OnSelectionChanged;
    }

    _set = true;
}

The SelectionChanged event is subscribed in SetVirtualView with a _set guard, but SetVirtualView can be called multiple times across the view's lifecycle. The standard MAUI handler pattern is to subscribe in ConnectHandler and unsubscribe in which already unsubscribesSelectionChangedusing the same_setflag. Using a secondary flag inSetVirtualViewis fragile and diverges fromTextChangedandFocusChangewhich correctly useConnectHandler/DisconnectHandler.DisconnectHandler

Recommendation: Move SelectionChanged subscription to ConnectHandler and remove the _set field and the SetVirtualView override:

protected override void ConnectHandler(MauiMaterialEditText platformView)
{
    platformView.TextChanged += OnTextChanged;
    platformView.FocusChange += OnFocusChange;
    platformView.SelectionChanged += OnSelectionChanged;  // move here
}

protected override void DisconnectHandler(MauiMaterialEditText platformView)
{
    platformView.TextChanged -= OnTextChanged;
    platformView.FocusChange -= OnFocusChange;
    platformView.SelectionChanged -= OnSelectionChanged;  // move here
    _set = false;  // _set can then be removed entirely
}

1. MauiMaterialEditText secondary constructors don't wrap context with theme

File: src/Core/src/Platform/Android/Material3Controls/MauiMaterialEditText.cs

The primary constructor correctly wraps the context:

public MauiMaterialEditText(Context context) : base(MauiMaterialContextThemeWrapper.Create(context))

But the secondary constructors do not:

public MauiMaterialEditText(Context context, IAttributeSet? attrs) : base(context, attrs)
public MauiMaterialEditText(Context context, IAttributeSet? attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)

This matches the pattern in MauiMaterialButton and other Material3 controls. While these constructors are less likely to be called in practice (the handler always uses the primary constructor), consistency is important for correctness.

Recommendation:

public MauiMaterialEditText(Context context, IAttributeSet? attrs)
    : base(MauiMaterialContextThemeWrapper.Create(context), attrs) { }

public MauiMaterialEditText(Context context, IAttributeSet? attrs, int defStyleAttr)
    : base(MauiMaterialContextThemeWrapper.Create(context), attrs, defStyleAttr) { }

2. Missing newline at end of file

Files:

  • src/Core/src/Handlers/Editor/EditorHandler2.Android. ends with }\ No newline at end of filecs
  • src/Core/src/Platform/Android/Material3Controls/MauiMaterialEditText. ends with }\ No newline at end of filecs

Both new files are missing a trailing newline. Add \n at the end of each file.

3. Handler registration could be simplified

File: src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs

Current:

#if ANDROID
    if (RuntimeFeature.IsMaterial3Enabled)
    {
        handlersCollection.AddHandler<Editor, EditorHandler2>();
    }
    else
    {
        handlersCollection.AddHandler<Editor, EditorHandler>();
    }
#else
    handlersCollection.AddHandler<Editor, EditorHandler>();
#endif

This duplicates the non-Material3 registration. Consider:

#if ANDROID
    handlersCollection.AddHandler(typeof(Editor),
        RuntimeFeature.IsMaterial3Enabled ? typeof(EditorHandler2) : typeof(EditorHandler));
#else
    handlersCollection.AddHandler<Editor, EditorHandler>();
#endif

4. No tests added

No unit or device tests were added for EditorHandler2. Given that this is a new handler class with distinct behavior (Material 3 styling, different platform view), basic tests verifying handler registration when IsMaterial3Enabled is true/false would improve confidence.


Looks Good

  • DataFlowDirection Correctly sets DataFlowDirection = DataFlowDirection.FromPlatform before calling VirtualView.UpdateText(e) and resets it after, preventing feedback loops. This matches the pattern used in EditorHandler.pattern
  • Property mapper EditorHandler2.Mapper covers all the same properties as EditorHandler (background, character spacing, font, read-only, text prediction, spell check, max length, placeholder, placeholder color, text, text color, alignment, keyboard, cursor position, selection length).completeness
  • IsFocused + Focus Correctly added in Editor.Mapper.cs when Material 3 is enabled, addressing the review comments.mappings
  • PlatformArrange Correctly calls this.PrepareForTextViewArrange(frame) before base.PlatformArrange(frame), consistent with EditorHandler.override
    Correctly callsVirtualView?.Completed() when focus is lost, matching the standard editor behavior.Completed()**
  • Class Both EditorHandler2 and MauiMaterialEditText are correctly internal with // TODO: Material3 - make it public in .net 11 comments, following the established Material3 staging pattern.visibility

@rmarinho rmarinho added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Feb 18, 2026
@SyedAbdulAzeemSF4852
Copy link
Copy Markdown
Contributor Author

Added UI tests and addressed all valid concerns.

@kubaflo kubaflo removed the s/agent-changes-requested AI agent recommends changes - found a better alternative or issues label Feb 25, 2026
@sheiksyedm
Copy link
Copy Markdown
Contributor

/azp run maui-pr-uitests

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@jfversluis jfversluis added this to the .NET 10 SR5 milestone Feb 27, 2026
@jfversluis jfversluis changed the base branch from main to inflight/current February 27, 2026 18:28
@jfversluis jfversluis merged commit 66a98de into dotnet:inflight/current Feb 28, 2026
4 of 12 checks passed
jfversluis added a commit that referenced this pull request Mar 2, 2026
### Description of Change

- This PR introduces Material Design 3 support for the Editor control on
Android.

### New classes (internal, TODO: make public in .NET 11):

- EditorHandler2 (EditorHandler2.Android.cs): A new handler extending
ViewHandler<IEditor, MauiMaterialEditText> that wraps
MauiMaterialEditText (a TextInputEditText-based view) instead of the
standard AppCompatEditText.

- Implements full property/command mapper parity with EditorHandler,
including DataFlowDirection tracking to distinguish platform-initiated
vs MAUI-initiated text updates. Subscribes to TextChanged, FocusChange,
and SelectionChanged events; calls VirtualView.Completed() on focus
loss; syncs CursorPosition/SelectionLength on selection changes.
Overrides PlatformArrange with PrepareForTextViewArrange.

- MauiMaterialEditText (MauiMaterialEditText.cs): Extends
TextInputEditText (from the Material library) to expose a
SelectionChanged event via override of OnSelectionChanged, enabling
cursor/selection position tracking by the handler. Wraps the context
with MauiMaterialContextThemeWrapper to apply the Material 3 theme.

### Handler registration (AppHostBuilderExtensions.cs):

- On Android, when RuntimeFeature.IsMaterial3Enabled is true,
EditorHandler2 is registered for Editor; otherwise the standard
EditorHandler is used.
- On all other platforms, the standard EditorHandler is used
(unchanged).

### Mapper setup (Editor.Mapper.cs, Editor.Android.cs):

- When Material 3 is enabled on Android, additional mappings are
registered on EditorHandler2.Mapper and EditorHandler2.CommandMapper:

- ReplaceMapping for Text and TextTransform → platform-overloaded
MapText (handles DataFlowDirection)
- AppendToMapping for IsFocused → InputView.MapIsFocused
- PrependToMapping for Focus → InputView.MapFocus

### Issues Fixed
Fixes #33476

### Output
| Material2 | Material3 |
|----------|----------|
| <img
src="https://github.com/user-attachments/assets/7d97f447-4228-4df8-b63d-8a8b96823734">
| <img
src="https://github.com/user-attachments/assets/1798d8bb-2f5a-40bd-97c8-cf9396d34d59">
|

---------

Co-authored-by: Gerald Versluis <gerald.versluis@microsoft.com>
jfversluis added a commit that referenced this pull request Mar 2, 2026
### Description of Change

- This PR introduces Material Design 3 support for the Editor control on
Android.

### New classes (internal, TODO: make public in .NET 11):

- EditorHandler2 (EditorHandler2.Android.cs): A new handler extending
ViewHandler<IEditor, MauiMaterialEditText> that wraps
MauiMaterialEditText (a TextInputEditText-based view) instead of the
standard AppCompatEditText.

- Implements full property/command mapper parity with EditorHandler,
including DataFlowDirection tracking to distinguish platform-initiated
vs MAUI-initiated text updates. Subscribes to TextChanged, FocusChange,
and SelectionChanged events; calls VirtualView.Completed() on focus
loss; syncs CursorPosition/SelectionLength on selection changes.
Overrides PlatformArrange with PrepareForTextViewArrange.

- MauiMaterialEditText (MauiMaterialEditText.cs): Extends
TextInputEditText (from the Material library) to expose a
SelectionChanged event via override of OnSelectionChanged, enabling
cursor/selection position tracking by the handler. Wraps the context
with MauiMaterialContextThemeWrapper to apply the Material 3 theme.

### Handler registration (AppHostBuilderExtensions.cs):

- On Android, when RuntimeFeature.IsMaterial3Enabled is true,
EditorHandler2 is registered for Editor; otherwise the standard
EditorHandler is used.
- On all other platforms, the standard EditorHandler is used
(unchanged).

### Mapper setup (Editor.Mapper.cs, Editor.Android.cs):

- When Material 3 is enabled on Android, additional mappings are
registered on EditorHandler2.Mapper and EditorHandler2.CommandMapper:

- ReplaceMapping for Text and TextTransform → platform-overloaded
MapText (handles DataFlowDirection)
- AppendToMapping for IsFocused → InputView.MapIsFocused
- PrependToMapping for Focus → InputView.MapFocus

### Issues Fixed
Fixes #33476

### Output
| Material2 | Material3 |
|----------|----------|
| <img
src="https://github.com/user-attachments/assets/7d97f447-4228-4df8-b63d-8a8b96823734">
| <img
src="https://github.com/user-attachments/assets/1798d8bb-2f5a-40bd-97c8-cf9396d34d59">
|

---------

Co-authored-by: Gerald Versluis <gerald.versluis@microsoft.com>
github-actions bot pushed a commit that referenced this pull request Mar 3, 2026
### Description of Change

- This PR introduces Material Design 3 support for the Editor control on
Android.

### New classes (internal, TODO: make public in .NET 11):

- EditorHandler2 (EditorHandler2.Android.cs): A new handler extending
ViewHandler<IEditor, MauiMaterialEditText> that wraps
MauiMaterialEditText (a TextInputEditText-based view) instead of the
standard AppCompatEditText.

- Implements full property/command mapper parity with EditorHandler,
including DataFlowDirection tracking to distinguish platform-initiated
vs MAUI-initiated text updates. Subscribes to TextChanged, FocusChange,
and SelectionChanged events; calls VirtualView.Completed() on focus
loss; syncs CursorPosition/SelectionLength on selection changes.
Overrides PlatformArrange with PrepareForTextViewArrange.

- MauiMaterialEditText (MauiMaterialEditText.cs): Extends
TextInputEditText (from the Material library) to expose a
SelectionChanged event via override of OnSelectionChanged, enabling
cursor/selection position tracking by the handler. Wraps the context
with MauiMaterialContextThemeWrapper to apply the Material 3 theme.

### Handler registration (AppHostBuilderExtensions.cs):

- On Android, when RuntimeFeature.IsMaterial3Enabled is true,
EditorHandler2 is registered for Editor; otherwise the standard
EditorHandler is used.
- On all other platforms, the standard EditorHandler is used
(unchanged).

### Mapper setup (Editor.Mapper.cs, Editor.Android.cs):

- When Material 3 is enabled on Android, additional mappings are
registered on EditorHandler2.Mapper and EditorHandler2.CommandMapper:

- ReplaceMapping for Text and TextTransform → platform-overloaded
MapText (handles DataFlowDirection)
- AppendToMapping for IsFocused → InputView.MapIsFocused
- PrependToMapping for Focus → InputView.MapFocus

### Issues Fixed
Fixes #33476

### Output
| Material2 | Material3 |
|----------|----------|
| <img
src="https://github.com/user-attachments/assets/7d97f447-4228-4df8-b63d-8a8b96823734">
| <img
src="https://github.com/user-attachments/assets/1798d8bb-2f5a-40bd-97c8-cf9396d34d59">
|

---------

Co-authored-by: Gerald Versluis <gerald.versluis@microsoft.com>
HarishKumarSF4517 pushed a commit to HarishKumarSF4517/maui that referenced this pull request Mar 5, 2026
### Description of Change

- This PR introduces Material Design 3 support for the Editor control on
Android.

### New classes (internal, TODO: make public in .NET 11):

- EditorHandler2 (EditorHandler2.Android.cs): A new handler extending
ViewHandler<IEditor, MauiMaterialEditText> that wraps
MauiMaterialEditText (a TextInputEditText-based view) instead of the
standard AppCompatEditText.

- Implements full property/command mapper parity with EditorHandler,
including DataFlowDirection tracking to distinguish platform-initiated
vs MAUI-initiated text updates. Subscribes to TextChanged, FocusChange,
and SelectionChanged events; calls VirtualView.Completed() on focus
loss; syncs CursorPosition/SelectionLength on selection changes.
Overrides PlatformArrange with PrepareForTextViewArrange.

- MauiMaterialEditText (MauiMaterialEditText.cs): Extends
TextInputEditText (from the Material library) to expose a
SelectionChanged event via override of OnSelectionChanged, enabling
cursor/selection position tracking by the handler. Wraps the context
with MauiMaterialContextThemeWrapper to apply the Material 3 theme.

### Handler registration (AppHostBuilderExtensions.cs):

- On Android, when RuntimeFeature.IsMaterial3Enabled is true,
EditorHandler2 is registered for Editor; otherwise the standard
EditorHandler is used.
- On all other platforms, the standard EditorHandler is used
(unchanged).

### Mapper setup (Editor.Mapper.cs, Editor.Android.cs):

- When Material 3 is enabled on Android, additional mappings are
registered on EditorHandler2.Mapper and EditorHandler2.CommandMapper:

- ReplaceMapping for Text and TextTransform → platform-overloaded
MapText (handles DataFlowDirection)
- AppendToMapping for IsFocused → InputView.MapIsFocused
- PrependToMapping for Focus → InputView.MapFocus

### Issues Fixed
Fixes dotnet#33476

### Output
| Material2 | Material3 |
|----------|----------|
| <img
src="https://github.com/user-attachments/assets/7d97f447-4228-4df8-b63d-8a8b96823734">
| <img
src="https://github.com/user-attachments/assets/1798d8bb-2f5a-40bd-97c8-cf9396d34d59">
|

---------

Co-authored-by: Gerald Versluis <gerald.versluis@microsoft.com>
github-actions bot pushed a commit that referenced this pull request Mar 6, 2026
### Description of Change

- This PR introduces Material Design 3 support for the Editor control on
Android.

### New classes (internal, TODO: make public in .NET 11):

- EditorHandler2 (EditorHandler2.Android.cs): A new handler extending
ViewHandler<IEditor, MauiMaterialEditText> that wraps
MauiMaterialEditText (a TextInputEditText-based view) instead of the
standard AppCompatEditText.

- Implements full property/command mapper parity with EditorHandler,
including DataFlowDirection tracking to distinguish platform-initiated
vs MAUI-initiated text updates. Subscribes to TextChanged, FocusChange,
and SelectionChanged events; calls VirtualView.Completed() on focus
loss; syncs CursorPosition/SelectionLength on selection changes.
Overrides PlatformArrange with PrepareForTextViewArrange.

- MauiMaterialEditText (MauiMaterialEditText.cs): Extends
TextInputEditText (from the Material library) to expose a
SelectionChanged event via override of OnSelectionChanged, enabling
cursor/selection position tracking by the handler. Wraps the context
with MauiMaterialContextThemeWrapper to apply the Material 3 theme.

### Handler registration (AppHostBuilderExtensions.cs):

- On Android, when RuntimeFeature.IsMaterial3Enabled is true,
EditorHandler2 is registered for Editor; otherwise the standard
EditorHandler is used.
- On all other platforms, the standard EditorHandler is used
(unchanged).

### Mapper setup (Editor.Mapper.cs, Editor.Android.cs):

- When Material 3 is enabled on Android, additional mappings are
registered on EditorHandler2.Mapper and EditorHandler2.CommandMapper:

- ReplaceMapping for Text and TextTransform → platform-overloaded
MapText (handles DataFlowDirection)
- AppendToMapping for IsFocused → InputView.MapIsFocused
- PrependToMapping for Focus → InputView.MapFocus

### Issues Fixed
Fixes #33476

### Output
| Material2 | Material3 |
|----------|----------|
| <img
src="https://github.com/user-attachments/assets/7d97f447-4228-4df8-b63d-8a8b96823734">
| <img
src="https://github.com/user-attachments/assets/1798d8bb-2f5a-40bd-97c8-cf9396d34d59">
|

---------

Co-authored-by: Gerald Versluis <gerald.versluis@microsoft.com>
PureWeen added a commit that referenced this pull request Mar 11, 2026
## What's Coming

.NET MAUI inflight/candidate introduces significant improvements across
all platforms with focus on quality, performance, and developer
experience. This release includes 46 commits with various improvements,
bug fixes, and enhancements.


## Button
- [Android] Implemented material3 support for Button by @Dhivya-SF4094
in #33173
  <details>
  <summary>🔧 Fixes</summary>

- [Implement Material3 support for
Button](#33172)
  </details>

## CollectionView
- [Android] Fix RemainingItemsThresholdReachedCommand not firing when
CollectionView has Header and Footer both defined by @SuthiYuvaraj in
#29618
  <details>
  <summary>🔧 Fixes</summary>

- [Android : RemainingItemsThresholdReachedCommand not firing when
CollectionVew has Header and Footer both
defined](#29588)
  </details>

- [iOS/MacCatalyst] Fix CollectionView ScrollTo for horizontal layouts
by @Shalini-Ashokan in #33853
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS/MacCatalyst] CollectionView ScrollTo does not work with
horizontal Layout](#33852)
  </details>

- [iOS & Mac] Fixed IndicatorView Size doesnt update dynamically by
@SubhikshaSf4851 in #31129
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS, Catalyst] IndicatorView.IndicatorSize does not update
dynamically at runtime](#31064)
  </details>

- [Android] Fix for CollectionView Scrolled event is triggered on the
initial app load. by @BagavathiPerumal in
#33558
  <details>
  <summary>🔧 Fixes</summary>

- [[Android] CollectionView Scrolled event is triggered on the initial
app load.](#33333)
  </details>

- [iOS, Android] Fix for CollectionView IsEnabled=false allows touch
interactions by @praveenkumarkarunanithi in
#31403
  <details>
  <summary>🔧 Fixes</summary>

- [More issues with CollectionView IsEnabled, InputTransparent, Opacity
via Styles and code behind](#19771)
  </details>

- [iOS] Fix VerticalOffset Update When Modifying
CollectionView.ItemsSource While Scrolled by @devanathan-vaithiyanathan
in #34153
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS]VerticalOffset Not Reset to Zero After Clearing ItemSource in
CollectionView](#26798)
  </details>

## DateTimePicker
- [Android] Fix DatePicker MinimumDate/MaximumDate not updating
dynamically by @HarishwaranVijayakumar in
#33687
  <details>
  <summary>🔧 Fixes</summary>

- [[regression/8.0.3] [Android] DatePicker control minimum date
issue](#19256)
- [[Android] DatePicker does not update MinimumDate / MaximumDate in the
Popup when set in the viewmodel after first
opening](#33583)
  </details>

## Drawing
- Android drawable perf by @albyrock87 in
#31567

## Editor
- [Android] Implemented material3 support for Editor by
@SyedAbdulAzeemSF4852 in #33478
  <details>
  <summary>🔧 Fixes</summary>

- [Implement Material3 Support for
Editor](#33476)
  </details>

## Entry
- [iOS, Mac] Fix for CursorPosition not updating when typing into Entry
control by @SyedAbdulAzeemSF4852 in
#30505
  <details>
  <summary>🔧 Fixes</summary>

- [Entry control CursorPosition does not update on TextChanged event
[iOS Maui 8.0.7] ](#20911)
- [CursorPosition not calculated correctly on behaviors events for iOS
devices](#32483)
  </details>

## Flyoutpage
- [Android, Windows] Fix for FlyoutPage toolbar button not updating on
orientation change by @praveenkumarkarunanithi in
#31962
  <details>
  <summary>🔧 Fixes</summary>

- [Flyout page in Android does not show flyout button (burger)
consistently](#24468)
  </details>

- Fix for First Item in CollectionView Overlaps in FlyoutPage.Flyout on
iOS by @praveenkumarkarunanithi in
#29265
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] CollectionView not rendering first item correctly in
FlyoutPage.Flyout](#29170)
  </details>

## Image
- [Android] Fix excessive memory usage for stream and resource-based
image loading by @Shalini-Ashokan in
#33590
  <details>
  <summary>🔧 Fixes</summary>

- [[Android] Unexpected high Bitmap.ByteCount when loading image via
ImageSource.FromResource() or ImageSource.FromStream() in .NET
MAUI](#33239)
  </details>

- [Android] Fix for Resize method returns an image that has already been
disposed by @SyedAbdulAzeemSF4852 in
#29964
  <details>
  <summary>🔧 Fixes</summary>

- [In GraphicsView, the Resize method returns an image that has already
been disposed](#29961)
- [IIMage.Resize bugged
behaviour](#31103)
  </details>

## Label
- Fixed Label Span font property inheritance when applied via Style by
@SubhikshaSf4851 in #34110
  <details>
  <summary>🔧 Fixes</summary>

- [`Span` does not inherit text styling from `Label` if that styling is
applied using `Style` ](#21326)
  </details>

- [Android] Implemented material3 support for Label by
@SyedAbdulAzeemSF4852 in #33599
  <details>
  <summary>🔧 Fixes</summary>

- [Implement Material3 Support for
Label](#33598)
  </details>

## Map
- [Android] Fix Circle Stroke color is incorrectly updated as Fill
color. by @NirmalKumarYuvaraj in
#33643
  <details>
  <summary>🔧 Fixes</summary>

- [[Android] Circle Stroke color is incorrectly updated as Fill
color.](#33642)
  </details>

## Mediapicker
- [iOS] Fix: invoke MediaPicker completion handler after
DismissViewController by @yuriikyry4enko in
#34250
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] Media Picker UIImagePickerController closing
issue](#21996)
  </details>

## Navigation
- Fix ContentPage memory leak on Android when using NavigationPage
modally (fixes #33918) by @brunck in
#34117
  <details>
  <summary>🔧 Fixes</summary>

- [[Android] Modal TabbedPage whose tabs are NavigationPage(ContentPage)
is retained after
PopModalAsync()](#33918)
  </details>

## Picker
- [Android] Implement material3 support for TimePicker by
@HarishwaranVijayakumar in #33646
  <details>
  <summary>🔧 Fixes</summary>

- [Implement Material3 support for
TimePicker](#33645)
  </details>

- [Android] Implemented Material3 support for Picker by
@SyedAbdulAzeemSF4852 in #33668
  <details>
  <summary>🔧 Fixes</summary>

- [Implement Material3 support for
Picker](#33665)
  </details>

## RadioButton
- [Android] Implemented material3 support for RadioButton by
@SyedAbdulAzeemSF4852 in #33468
  <details>
  <summary>🔧 Fixes</summary>

- [Implement Material3 Support for
RadioButton](#33467)
  </details>

## Setup
- Clarify MA003 error message by @jeremy-visionaid in
#34067
  <details>
  <summary>🔧 Fixes</summary>

- [MA003 false positive with
9.0.21](#26599)
  </details>

## Shell
- [Android] Fix TabBar FlowDirection not updating dynamically by
@SubhikshaSf4851 in #33091
  <details>
  <summary>🔧 Fixes</summary>

- [[Android, iOS] FlowDirection RTL is not updated dynamically on Shell
TabBar](#32993)
  </details>

- [Android] Fix page not disposed on Shell replace navigation by
@Vignesh-SF3580 in #33426
  <details>
  <summary>🔧 Fixes</summary>

- [[Android] [Shell] replace navigation leaks current
page](#25134)
  </details>

- [Android] Fixed Shell flyout does not disable scrolling when
FlyoutVerticalScrollMode is set to Disabled by @NanthiniMahalingam in
#32734
  <details>
  <summary>🔧 Fixes</summary>

- [[Android] Shell.FlyoutVerticalScrollMode="Disabled" does not disable
scrolling](#32477)
  </details>

## Single Project
- Fix: Throw a clear error when an SVG lacks dimensions instead of a
NullReferenceException by @Shalini-Ashokan in
#33194
  <details>
  <summary>🔧 Fixes</summary>

- [MAUI Fails To Convert Valid SVG Files Into PNG Files (Object
reference not set to an instance of an
object)](#32460)
  </details>

## SwipeView
- [iOS] Fix SwipeView stays open on iOS after updating content by
@devanathan-vaithiyanathan in #31248
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] - Swipeview with collectionview
issue](#19541)
  </details>

## TabbedPage
- [Windows] Fixed IsEnabled Property not works on Tabs by
@NirmalKumarYuvaraj in #26728
  <details>
  <summary>🔧 Fixes</summary>

- [ShellContent IsEnabledProperty does not
work](#5161)
- [[Windows] Shell Tab IsEnabled Not
Working](#32996)
  </details>

- [Android] Fix NavigationBar overlapping StatusBar when NavigationBar
visibility changes by @Vignesh-SF3580 in
#33359
  <details>
  <summary>🔧 Fixes</summary>

- [[Android] NavigationBar overlaps with StatusBar when mixing
HasNavigationBar=true/false in TabbedPage on Android 15 (API
35)](#33340)
  </details>

## Templates
- Fix for unable to open task using keyboard navigation on windows
platform by @SuthiYuvaraj in #33647
  <details>
  <summary>🔧 Fixes</summary>

- [Unable to open task using keyboard: A11y_.NET maui_User can get all
the insights of
Dashboard_Keyboard](#30787)
  </details>

## TitleView
- Fix for NavigationPage.TitleView does not expand with host window in
iPadOS 26+ by @SuthiYuvaraj in #33088

## Toolbar
- [iOS] Fix toolbar items ignoring BarTextColor on iOS/MacCatalyst 26+
by @Shalini-Ashokan in #34036
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS 26] ToolbarItem color with custom BarTextColor not
working](#33970)
  </details>

- [Android] Fix for ToolbarItem retaining the icon from the previous
page on Android when using NavigationPage. by @BagavathiPerumal in
#32311
  <details>
  <summary>🔧 Fixes</summary>

- [Toolbaritem keeps the icon of the previous page on Android, using
NavigationPage (not shell)](#31727)
  </details>

## WebView
- [Android] Fix WebView in a grid expands beyond it's cell by
@devanathan-vaithiyanathan in #32145
  <details>
  <summary>🔧 Fixes</summary>

- [Android - WebView in a grid expands beyond it's
cell](#32030)
  </details>

## Xaml
- ContentPresenter: Propagate binding context to children with explicit
TemplateBinding by @HarishwaranVijayakumar in
#30880
  <details>
  <summary>🔧 Fixes</summary>

- [Binding context in
ContentPresenter](#23797)
  </details>


<details>
<summary>🔧 Infrastructure (1)</summary>

- [Revert] ContentPresenter: Propagate binding context to children with
explicit TemplateBinding by @Ahamed-Ali in
#34332

</details>

<details>
<summary>🧪 Testing (6)</summary>

- [Testing] Feature Matrix UITest Cases for Shell Flyout Page by
@NafeelaNazhir in #32525
- [Testing] Feature Matrix UITest Cases for Brushes by
@LogishaSelvarajSF4525 in #31833
- [Testing] Feature Matrix UITest Cases for BindableLayout by
@LogishaSelvarajSF4525 in #33108
- [Android] Add UI tests for Material 3 CheckBox by
@HarishwaranVijayakumar in #34126
  <details>
  <summary>🔧 Fixes</summary>

- [[Android] Add UI tests for Material 3
CheckBox](#34125)
  </details>
- [Testing] Feature Matrix UITest Cases for Shell Tabbed Page by
@NafeelaNazhir in #33159
- [Testing] Fixed Test case failure in PR 34294 - [03/2/2026] Candidate
- 1 by @TamilarasanSF4853 in #34334

</details>

<details>
<summary>📦 Other (2)</summary>

- Bumps Syncfusion.Maui.Toolkit dependency to version 1.0.9 by
@PaulAndersonS in #34178
- Fix crash when closing Windows based app when using TitleBar by
@MFinkBK in #34032
  <details>
  <summary>🔧 Fixes</summary>

- [Unhandled exception "Value does not fall within the expected range"
when closing Windows app](#32194)
  </details>

</details>
**Full Changelog**:
main...inflight/candidate
@kubaflo kubaflo added the s/agent-review-incomplete AI agent could not complete all phases (blocker, timeout, error) label Mar 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-controls-editor Editor community ✨ Community Contribution material3 partner/syncfusion Issues / PR's with Syncfusion collaboration platform/android s/agent-review-incomplete AI agent could not complete all phases (blocker, timeout, error) s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Material3 Support for Editor

6 participants