Rich text editing for .NET MAUI, rendered entirely on a SkiaSharp canvas.
MintedTextEditor is organized into three packages:
MintedTextEditor.Core: document model, editing engine, layout, formatting, commands, events, HTML and Markdown interop.MintedTextEditor.SkiaSharp: drawing backend implementingIDrawingContext, with HarfBuzz text shaping.MintedTextEditor.Maui: MAUI control (MintedEditorView) and platform integration.
- Highlights
- Package Layout
- Platform Support
- Quick Start
- Sample App
- Configuration
- Documentation
- Build and Test
- Contributing
- Code of Conduct
- License
- Full-canvas rendering using SkiaSharp (no native text editor controls).
- Character formatting: bold, italic, underline, strikethrough, subscript, superscript, font family/size, text color, highlight.
- Paragraph formatting: alignment, indentation, line spacing, headings, lists, block quote.
- Inline content: hyperlinks, images, tables.
- Editing primitives: caret navigation, selection, clipboard, undo/redo, find and replace.
- Touch caret drag with a native-style magnifier (loupe), configurable or switchable off.
- Themed, canvas-drawn context menu (cut, copy, paste, select all, hyperlink, image and table actions) on right-click or long press, with keyboard navigation and customizable items.
- Text shaped with HarfBuzz (kerning, ligatures, complex scripts); emoji, ZWJ sequences and flags draw as one glyph and are never split by the caret, Backspace, wrapping or hit-testing.
- Android soft-keyboard and IME support (composition, suggestions, dead keys on hardware keyboards).
- Toolbar and command architecture with customizable item sets.
- Three built-in toolbar icon packs (Lucide, Heroicons, Material Symbols) — all embedded in the
MintedTextEditor.Corepackage, no app-bundle asset setup required. - Theme-aware toolbar icons: automatically recolored to the current theme's foreground at draw time, including full dark-mode support.
- HTML and Markdown import/export pipelines, including support for GitHub Flavored Markdown (GFM).
- Theming support (light, dark, high contrast, and custom styles).
- Right-to-left paragraphs and replaceable UI strings (
EditorStrings). - Basic screen-reader support: the editor is announced as one element with a localizable description and hint (read-only state, placeholder); document content and the canvas-drawn toolbar are not exposed yet (details).
src/
MintedTextEditor.Core/
MintedTextEditor.SkiaSharp/
MintedTextEditor.Maui/
samples/
SampleApp.Maui/
tests/
MintedTextEditor.Core.Tests/
MintedTextEditor.SkiaSharp.Tests/
| Platform | Minimum Version |
|---|---|
| Android | API 21 (Android 5.0) |
| iOS | 15.0 |
| macOS (Mac Catalyst) | 15.0 |
| Windows | 10.0.17763 (the Windows target is only built on a Windows machine) |
dotnet add package MintedTextEditor.MauiThis brings in MintedTextEditor.Core, MintedTextEditor.SkiaSharp, SkiaSharp 4.153.1 (SkiaSharp.Views.Maui.Controls), HarfBuzzSharp and Svg.Skia 5.2.3. The packages target .NET 10 / MAUI 10.
In MauiProgram.cs:
using MintedTextEditor.Maui;
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseMintedTextEditor();<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:minted="https://schemas.mintedtexteditor.com/2026"
x:Class="MyApp.MainPage">
<minted:MintedEditorView
x:Name="Editor"
ShowToolbar="True"
PlaceholderText="Start typing..." />
</ContentPage>Editor.LoadHtml("<p>Hello <strong>world</strong></p>");
string html = Editor.GetHtml();Editor.LoadMarkdown("# Hello World\nThis is a paragraph.");
string markdown = Editor.GetMarkdown();For full import/export options, including GitHub Flavored Markdown (GFM) support, see docs/markdown-interop.md.
The repository includes a runnable MAUI sample with focused pages for:
- basic editing and read-only mode
- formatting
- load/save, HTML, and Markdown
- images and hyperlinks
- tables
- custom commands and a dynamic toolbar
- event monitoring
- localization
- theming and toolbar icon packs
Project: samples/SampleApp.Maui
using MintedTextEditor.Core.Theming;
Editor.Theme = EditorTheme.CreateDark();
Editor.UseSystemTheme = false;Three icon packs are included and embedded in MintedTextEditor.Core — no extra files are needed in the app project.
| Pack | Style |
|---|---|
ToolbarIconPack.Lucide |
Outlined, 2 px stroke (default) |
ToolbarIconPack.Heroicons |
Outlined, 1.5 px stroke |
ToolbarIconPack.MaterialSymbols |
Filled, Material Design paths |
using MintedTextEditor.Core.Toolbar;
Editor.ToolbarIconPack = ToolbarIconPack.Lucide; // default
Editor.ToolbarIconPack = ToolbarIconPack.Heroicons;
Editor.ToolbarIconPack = ToolbarIconPack.MaterialSymbols;All icons are rendered with black ink and recolored at draw time using SKColorFilter (SrcIn) to match the current theme color. Switching between light and dark themes updates icon colors automatically without reloading assets.
using MintedTextEditor.Core.Markdown;
Editor.AppendMarkdown("## Subheading\nAnother paragraph.");
var markdown = Editor.GetMarkdown(new MarkdownExportOptions
{
UseGfmExtensions = true, // GitHub Flavored Markdown: tables, ~~strikethrough~~ (default: true)
LineEnding = "\r\n" // default: "\n"
});On touch screens, press and hold to pick up the caret and drag it; a magnifier shows the line under your finger.
using MintedTextEditor.Core.Editing;
Editor.IsMagnifierEnabled = false; // turn it off
Editor.MagnifierOptions = MagnifierOptions.Android; // or customise size, zoom, border, shadowRight-click, long-press the selection, or long-press without dragging to open the context menu. Customize its items with ContextMenuItemsRequested, or turn it off:
Editor.IsContextMenuEnabled = false;Editor.Focus(); // focus the editor and show the soft keyboard
bool focused = Editor.IsEditorFocused;
Editor.EditorFocusChanged += (_, e) => { /* e.IsFocused */ };EditorFocusChanged fires once per real native focus change, including a tap into the editor or focus moving to another control. The editor starts unfocused.
Editor.FindNext("draft"); // select and scroll to the next match (wraps)
Editor.FindPrevious("draft", matchCase: true);
Editor.Replace("draft", "final"); // replace the selected match, select the next
int replaced = Editor.ReplaceAll("draft", "final"); // one undo step
Editor.FindReplaceCompleted += (_, e) => { /* e.MatchCount, e.CurrentMatchIndex */ };There is no built-in find bar; see docs/commands-events.md.
Editor.TextChanged += (_, e) => { /* document changed */ };
Editor.SelectionChanged += (_, e) => { /* selection changed */ };
Editor.HyperlinkClicked += (_, e) => { /* e.Url; set e.Cancel to stop the default open */ };
Editor.FontAttributesChanged += (_, e) => { /* e.IsBold, e.IsItalic … at the caret/selection */ };
Editor.ImageInserted += (_, e) => { /* e.Image */ };
Editor.ContentLoaded += (_, e) => { /* after LoadHtml / LoadMarkdown */ };The formatting events (font, size, colours, bold/italic, underline/strikethrough, heading, alignment, list type) fire only when the formatting at the caret or selection actually changes; Editor.CurrentFormatting holds the latest values.
For deeper API details, see docs/getting-started.md, docs/commands-events.md, and docs/toolbar-customization.md.
| Document | Description |
|---|---|
| Getting Started | Installation, setup, first editor |
| Document Model | Blocks, inlines, and text runs |
| Formatting | Character and paragraph formatting |
| Toolbar Customization | Toolbar groups and items |
| Theming | Built-in and custom themes |
| Commands & Events | Command and event reference |
| HTML Interop | HTML import/export behavior |
| Markdown Interop | Markdown import/export behavior |
| Images & Hyperlinks | Inline media and links |
| Tables | Table creation and editing |
| Accessibility | Accessibility guidance |
| Architecture | Internal architecture overview |
git clone https://github.com/TheEightBot/MintedTextEditor.git
cd MintedTextEditor
# Build and test the platform-independent projects (any OS, no MAUI workload)
dotnet build MintedTextEditor.Core.slnf
dotnet test MintedTextEditor.Core.slnf
# Build MAUI project and sample app (needs the MAUI workload; iOS/Mac Catalyst need macOS)
dotnet workload install maui
dotnet build src/MintedTextEditor.Maui/
dotnet build samples/SampleApp.Maui/Contributions are welcome. Please read CONTRIBUTING.md before opening a pull request.
This project follows the Contributor Covenant Code of Conduct.
