Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
5cffe6c
Icons regardless of type, library updates, and other improvements
Onebeld Jun 14, 2026
e28d030
Replace PathIcon with IconControl where possible and various fixes
Onebeld Jun 14, 2026
1be17e2
SmoothScrollViewer, MaterialIcons generator have been removed, IconCo…
Onebeld Jun 16, 2026
a8f0499
Added documentation for ScrollViewerExtensions, improved functionalit…
Onebeld Jun 17, 2026
a425bcf
More detailed attribution, improved ScrollViewerExtensions, removal o…
Onebeld Jun 20, 2026
2c7eda5
Reworked NoticeDialog, renamed to PleasantIcon, added ColorPicker, an…
Onebeld Jun 27, 2026
2f26e26
Removing VGUI, installing fonts, Composition animations, and other ch…
Onebeld Jun 28, 2026
2dec3ea
Removed PleasantReDock, added philosophy to README, added documentati…
Onebeld Jun 29, 2026
535f0c1
Introducing SearchableComboBox
Onebeld Jun 30, 2026
26164f9
Localization key generation and usage analysis, virtualized Searchabl…
Onebeld Jul 2, 2026
ec92090
Refining the analyzer, adding tests
Onebeld Jul 4, 2026
b2f6604
Analysis of keys that are missing from resx, property for disabling t…
Onebeld Jul 4, 2026
148c322
Fix for implicit animations, improved ScrollViewer smooth scrolling, …
Onebeld Jul 5, 2026
6050c04
Refactoring of NavigationView, fixing Tab focus behavior, and correct…
Onebeld Jul 6, 2026
7a29bf5
Continued rework of NavigationView, removal of PleasantFlyout, modifi…
Onebeld Jul 7, 2026
540d0e4
PleasantWindow refinements, focus fixes, and more
Onebeld Jul 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
65 changes: 39 additions & 26 deletions PleasantUI.sln
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,31 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PleasantUI.DataGrid", "src\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PleasantUI.Example", "samples\PleasantUI.Example\PleasantUI.Example.csproj", "{59DC0F4B-421E-407D-9435-F6ED14765634}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "designer", "designer", "{EBAC1577-CFD7-477C-848E-86BFFC345D90}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PleasantUI.ToolKit", "src\PleasantUI.ToolKit\PleasantUI.ToolKit.csproj", "{722B39BB-1CBF-4762-A5C5-439F4EB3A781}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PleasantUI.Designer", "designer\PleasantUI.Designer\PleasantUI.Designer.csproj", "{88C264B9-51D4-41CF-AEC0-24F5075FA6B8}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_build", "_build", "{D6E493DE-5180-4BA0-B122-D155A5934D08}"
ProjectSection(SolutionItems) = preProject
build\Package.props = build\Package.props
build\PleasantUI.targets = build\PleasantUI.targets
build\PleasantUI.Localization.Analyzer.targets = build\PleasantUI.Localization.Analyzer.targets
build\PleasantUI.Localization.Generator.targets = build\PleasantUI.Localization.Generator.targets
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "generators", "generators", "{941F7A66-EFCB-4141-97CA-A0B779ED1BB4}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "generators", "generators", "{77203EAD-CB0D-4D37-B8E7-2F2BA0A1B1EF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PleasantUI.MaterialIcons", "src\PleasantUI.MaterialIcons\PleasantUI.MaterialIcons.csproj", "{2ABE0576-837B-4D1B-970D-00B52BF0E078}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PleasantUI.Localization.Generator", "generators\PleasantUI.Localization.Generator\PleasantUI.Localization.Generator.csproj", "{967BBBAA-7F6F-4DA6-A8E5-9F0A70DFF684}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PleasantUI.MaterialIcons.SourceGenerator", "generators\PleasantUI.MaterialIcons.SourceGenerator\PleasantUI.MaterialIcons.SourceGenerator.csproj", "{9FDFD065-7664-4E0C-B928-D7FC8B074EDD}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "analyzers", "analyzers", "{20ECD7A9-C3D1-41AA-A8BB-640E3B28BBC0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PleasantUI.ToolKit", "src\PleasantUI.ToolKit\PleasantUI.ToolKit.csproj", "{722B39BB-1CBF-4762-A5C5-439F4EB3A781}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PleasantUI.Localization.Analyzer", "analyzers\PleasantUI.Localization.Analyzer\PleasantUI.Localization.Analyzer.csproj", "{A519CDCF-2774-4FD9-AE5F-0F6B62F7C346}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{D6E493DE-5180-4BA0-B122-D155A5934D08}"
ProjectSection(SolutionItems) = preProject
build\Package.props = build\Package.props
EndProjectSection
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_tests", "_tests", "{80E17402-8124-43B7-A0BB-E939CDD20E21}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "analyzers", "analyzers", "{6B8337BF-8256-47CF-836E-C5A3C745D931}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PleasantUI.Localization.Analyzer.Tests", "tests\analyzers\PleasantUI.Localization.Analyzer.Tests\PleasantUI.Localization.Analyzer.Tests.csproj", "{D3E71BE9-D438-48ED-A99D-EF30AEFD66A5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "common", "common", "{4BCCA866-A31E-49B1-AB79-B9C94651D295}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PleasantUI.Tests", "tests\PleasantUI.Tests\PleasantUI.Tests.csproj", "{A6230EC5-60E1-41E8-BE8E-CA9A82D7F835}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -57,29 +64,35 @@ Global
{59DC0F4B-421E-407D-9435-F6ED14765634}.Debug|Any CPU.Build.0 = Debug|Any CPU
{59DC0F4B-421E-407D-9435-F6ED14765634}.Release|Any CPU.ActiveCfg = Release|Any CPU
{59DC0F4B-421E-407D-9435-F6ED14765634}.Release|Any CPU.Build.0 = Release|Any CPU
{88C264B9-51D4-41CF-AEC0-24F5075FA6B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{88C264B9-51D4-41CF-AEC0-24F5075FA6B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88C264B9-51D4-41CF-AEC0-24F5075FA6B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{88C264B9-51D4-41CF-AEC0-24F5075FA6B8}.Release|Any CPU.Build.0 = Release|Any CPU
{2ABE0576-837B-4D1B-970D-00B52BF0E078}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2ABE0576-837B-4D1B-970D-00B52BF0E078}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2ABE0576-837B-4D1B-970D-00B52BF0E078}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2ABE0576-837B-4D1B-970D-00B52BF0E078}.Release|Any CPU.Build.0 = Release|Any CPU
{9FDFD065-7664-4E0C-B928-D7FC8B074EDD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9FDFD065-7664-4E0C-B928-D7FC8B074EDD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9FDFD065-7664-4E0C-B928-D7FC8B074EDD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9FDFD065-7664-4E0C-B928-D7FC8B074EDD}.Release|Any CPU.Build.0 = Release|Any CPU
{722B39BB-1CBF-4762-A5C5-439F4EB3A781}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{722B39BB-1CBF-4762-A5C5-439F4EB3A781}.Debug|Any CPU.Build.0 = Debug|Any CPU
{722B39BB-1CBF-4762-A5C5-439F4EB3A781}.Release|Any CPU.ActiveCfg = Release|Any CPU
{722B39BB-1CBF-4762-A5C5-439F4EB3A781}.Release|Any CPU.Build.0 = Release|Any CPU
{967BBBAA-7F6F-4DA6-A8E5-9F0A70DFF684}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{967BBBAA-7F6F-4DA6-A8E5-9F0A70DFF684}.Debug|Any CPU.Build.0 = Debug|Any CPU
{967BBBAA-7F6F-4DA6-A8E5-9F0A70DFF684}.Release|Any CPU.ActiveCfg = Release|Any CPU
{967BBBAA-7F6F-4DA6-A8E5-9F0A70DFF684}.Release|Any CPU.Build.0 = Release|Any CPU
{A519CDCF-2774-4FD9-AE5F-0F6B62F7C346}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A519CDCF-2774-4FD9-AE5F-0F6B62F7C346}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A519CDCF-2774-4FD9-AE5F-0F6B62F7C346}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A519CDCF-2774-4FD9-AE5F-0F6B62F7C346}.Release|Any CPU.Build.0 = Release|Any CPU
{D3E71BE9-D438-48ED-A99D-EF30AEFD66A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D3E71BE9-D438-48ED-A99D-EF30AEFD66A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D3E71BE9-D438-48ED-A99D-EF30AEFD66A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D3E71BE9-D438-48ED-A99D-EF30AEFD66A5}.Release|Any CPU.Build.0 = Release|Any CPU
{A6230EC5-60E1-41E8-BE8E-CA9A82D7F835}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A6230EC5-60E1-41E8-BE8E-CA9A82D7F835}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A6230EC5-60E1-41E8-BE8E-CA9A82D7F835}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A6230EC5-60E1-41E8-BE8E-CA9A82D7F835}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{71BFCFA6-B53E-4F28-819F-51CB26516B5A} = {BEE78D8A-ED3D-4D34-9B29-43D5BB953D40}
{91F6CDD0-6925-4289-90EC-8BDD245F7BD0} = {BEE78D8A-ED3D-4D34-9B29-43D5BB953D40}
{59DC0F4B-421E-407D-9435-F6ED14765634} = {BEE78D8A-ED3D-4D34-9B29-43D5BB953D40}
{88C264B9-51D4-41CF-AEC0-24F5075FA6B8} = {EBAC1577-CFD7-477C-848E-86BFFC345D90}
{9FDFD065-7664-4E0C-B928-D7FC8B074EDD} = {941F7A66-EFCB-4141-97CA-A0B779ED1BB4}
{2ABE0576-837B-4D1B-970D-00B52BF0E078} = {4BCCA866-A31E-49B1-AB79-B9C94651D295}
{967BBBAA-7F6F-4DA6-A8E5-9F0A70DFF684} = {77203EAD-CB0D-4D37-B8E7-2F2BA0A1B1EF}
{A519CDCF-2774-4FD9-AE5F-0F6B62F7C346} = {20ECD7A9-C3D1-41AA-A8BB-640E3B28BBC0}
{6B8337BF-8256-47CF-836E-C5A3C745D931} = {80E17402-8124-43B7-A0BB-E939CDD20E21}
{D3E71BE9-D438-48ED-A99D-EF30AEFD66A5} = {6B8337BF-8256-47CF-836E-C5A3C745D931}
{A6230EC5-60E1-41E8-BE8E-CA9A82D7F835} = {80E17402-8124-43B7-A0BB-E939CDD20E21}
EndGlobalSection
EndGlobal
23 changes: 18 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,16 @@

> **Repositories:** [Original (Onebeld)](https://github.com/Onebeld/PleasantUI) · [Fork (ghudulf)](https://github.com/ghudulf/PleasantUI)

PleasantUI is a cross-platform UI theme and control library for [Avalonia](https://github.com/AvaloniaUI/Avalonia), inspired by Microsoft Fluent Design and the WinUI/UWP visual language. It completely re-styles every standard Avalonia control and adds a suite of custom controls, a multi-theme engine with custom theme support, a reactive localization system, and a custom window chrome — all AOT-compatible with no `rd.xml` required.
PleasantUI is a cross-platform UI theme and control library for [Avalonia](https://github.com/AvaloniaUI/Avalonia), inspired by Microsoft Fluent Design, Google Material Design and the WinUI/UWP visual language. It completely re-styles every standard Avalonia control and adds a suite of custom controls, a multi-theme engine with custom theme support, a reactive localization system, and a custom window chrome — all AOT-compatible with no `rd.xml` required.

The project has been in active development since 2021, originally as part of the [Regul](https://github.com/Onebeld/Regul) and [Regul Save Cleaner](https://github.com/Onebeld/RegulSaveCleaner) projects.

## 🏛️ Philosophy

The philosophy is to provide the user with a _**pleasant**_ experience in using applications built on this library. This library isn't intended to be compared to other design principles or other UI libraries. If the interface looks good, then this library is doing its job.

This library may also contain elements from other design principles or UI libraries if it makes the interface _**pleasant**_ enough (but with due attribution, of course).

## ✨ Features

### Complete Fluent-style control theming
Expand Down Expand Up @@ -47,7 +53,6 @@ Controls built from scratch that go beyond what Avalonia ships:
| `InformationBlock` | Compact pill-shaped label combining an icon and a value | ![Imgur](https://i.imgur.com/SX0BZ2k.png) |
| `MarkedTextBox` / `MarkedNumericUpDown` | Input controls with inline label/unit markers | None |
| `RippleEffect` | Material-style ripple click feedback | ![Imgur](https://i.imgur.com/2WtIPvj.gif) |
| `SmoothScrollViewer` | ScrollViewer with inertia gesture support | None |
| `PleasantMiniWindow` | Lightweight floating window | None |
| `Timeline` | Displays a list of events in chronological order along a vertical axis. Supports four layout modes, custom icons, and five severity types. | ![Imgur](https://i.imgur.com/DGP3nDR.png) |
| `InstallWizard` | A multi-step installation wizard with a sidebar step list, progress bar, and Back / Next / Cancel navigation. | ![Imgur](https://i.imgur.com/bbgKH3L.png) |
Expand Down Expand Up @@ -311,9 +316,17 @@ string title = Localizer.TrDefault("DialogTitle", "Confirm");

## ❤️ Credits

- [Avalonia](https://github.com/AvaloniaUI/Avalonia)
- Some controls inspired by PieroCastillo's [Aura.UI](https://github.com/PieroCastillo/Aura.UI)
- [ProgressRing](https://github.com/ymg2006/FluentAvalonia.ProgressRing) by ymg2006
### Main
- [Avalonia](https://github.com/AvaloniaUI/Avalonia) under license from MIT
- Built with [JetBrains Rider](https://www.jetbrains.com/rider/)

### Controls and Code
- [Aura.UI](https://github.com/PieroCastillo/Aura.UI) (PieroCastillo) - NavigationView and AuraTabView under license from MIT
- [ProgressRing](https://github.com/ymg2006/FluentAvalonia.ProgressRing) (ymg2006) - under license from MIT
- [RichTextKit](https://github.com/toptensoftware/RichTextKit) (toptensoftware) - implementation of BinarySearch under license from Apache 2.0
- [weather](https://github.com/rocksdanister/weather) (rocksdanister) - implementation of BackdropBlurBorder under license from MIT
- [Xaml.Behaviors.Interactions.Animated](https://github.com/Egolds/Xaml.Behaviors.Interactions.Animated) (Egolds) - implementation of VerticalScrollViewerAnimatedBehavior under license from MIT
- [BilibiliClient](https://github.com/afunc233/BilibiliClient) (afunc233) - implementation of VirtualizingWrapPanel
- [Material.Avalonia](https://github.com/AvaloniaCommunity/Material.Avalonia) (CommunityAvalonia) - implementation of Ripple Effect under license from MIT

<img src="https://i.imgur.com/IvbDwuz.png" width="360" align="right"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## Release 1.0

### New Rules

| Rule ID | Category | Severity | Notes |
|---------|----------|----------|--------------------------------------------------|
| AB0001 | Naming | Warning | Type names should not contain the company name. |
| AB0002 | Usage | Warning | The speed must be lower than the Speed of Light. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
### New Rules

| Rule ID | Category | Severity | Notes |
|---------|----------|----------|-------|
PUILOC101 | Localization | Warning | ResxUsageAnalyzer
PUILOC102 | Localization | Warning | MissingResxKeyAnalyzer
61 changes: 61 additions & 0 deletions analyzers/PleasantUI.Localization.Analyzer/LocExclusions.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
AttachOverWindows
Back
Cancel
ChangeMenu
Close
CloseMenu
Collapse
CollapseMenu
ColorWheel
Confirm
CopyMenu
CutMenu
DeleteMenu
Expand
ExpandMenu
Menu
Next
NoItems
Off
Ok
On
PasteMenu
PathPicker/OpenFile
Restore
RestoreMenu
SearchableComboBox/SearchPlaceholder
Theme/Light
Theme/Cave
Theme/Cherry
Theme/Custom
Theme/Dark
Theme/Ice
Theme/Lunar
Theme/Sunny
Theme/System
Theme/Mint
Theme/Spruce
Theme/Strawberry
ToolKit/AddColor
ToolKit/AddYourNewColor
ToolKit/Colors
ToolKit/CustomThemes
ToolKit/NoCustomThemes
ToolKit/Redo
ToolKit/SavedColors
ToolKit/ThemeEditor
ToolKit/ThemeEditor/ColorCopiedToClipboard
ToolKit/ThemeEditor/CopyTheme
ToolKit/ThemeEditor/DragAndDropThemeHere
ToolKit/ThemeEditor/ExportTheme
ToolKit/ThemeEditor/GetColorsBasedOn
ToolKit/ThemeEditor/ImportTheme
ToolKit/ThemeEditor/NumberOfColorsInstalled
ToolKit/ThemeEditor/PasteTheme
ToolKit/ThemeEditor/ThemeCopiedToClipboard
ToolKit/ThemeEditor/ThemeExported
ToolKit/ThemeEditor/ThemeImported
ToolKit/ThemeEditor/ThemeImportError
ToolKit/ThemeEditor/ThemeName
ToolKit/Themes
ToolKit/Undo
Loading