Skip to content

Repository files navigation

GitHub LicenseGitHub repo sizeNugetGitHub release (with filter)

Imgur

PleasantUI

Repositories:Original (Onebeld) · Fork (ghudulf)

PleasantUI is a cross-platform UI theme and control library for 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 and Regul Save Cleaner 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 control theming

Every standard Avalonia control is receiving a complete overhaul: rounded corners, multi-layered fills, smooth transitions on hover and click, and accent color integration:

ControlControlControl
Button (+ AppBar, Accent, Danger variants)CheckBoxRadioButton
ToggleButton / ToggleSwitchRepeatButton / ButtonSpinnerSlider
TextBox / AutoCompleteBoxNumericUpDownComboBox / DropDownButton
Calendar / CalendarDatePicker / TimePickerDataGridListBox / TreeView
ExpanderTabControl / TabItemScrollBar / ScrollViewer
ProgressBarMenu / ContextMenuToolTip
CarouselSeparatorNotificationCard

Custom Pleasant controls

Controls built from scratch that go beyond what Avalonia ships:

ControlDescriptionDemo
PleasantWindowCustom window chrome with a Fluent title bar, subtitle, custom icon/title content, optional blur, content-extends-into-titlebar, and macOS caption overrideNone
NavigationView / NavigationViewItemCollapsible side navigation panel, similar to WinUI NavigationViewNone
PleasantTabView / PleasantTabItemChromium-style tab strip with add/close buttons and scrollable tab barNone
ContentDialogModal overlay dialog with bottom button panel and smooth scroll content areaNone
PleasantSnackbarTemporary non-intrusive notification barImgur
ProgressRingCircular progress indicator — both determinate and indeterminate with animated arcImgur
OptionsDisplayItemSettings-style row with header, description, icon, action button slot, navigation chevron, and expandable contentImgur
InformationBlockCompact pill-shaped label combining an icon and a valueImgur
MarkedTextBox / MarkedNumericUpDownInput controls with inline label/unit markersNone
RippleEffectMaterial-style ripple click feedbackImgur
PleasantMiniWindowLightweight floating windowNone
TimelineDisplays a list of events in chronological order along a vertical axis. Supports four layout modes, custom icons, and five severity types.Imgur
InstallWizardA multi-step installation wizard with a sidebar step list, progress bar, and Back / Next / Cancel navigation.Imgur
PleasantMenuA customizable flyout menu with a title, optional info badges, a grid of large icon buttons, and a footer bar with small utility buttons.Imgur
PathPickerCombines a read-only TextBox with a browse button. Supports OpenFile, SaveFile, and OpenFolder modes, optional multi-select, file-type filters, and two-way binding on the selected path text.Imgur
PopConfirmWraps any trigger control and shows a small popup with a header, body, and Confirm / Cancel buttons before executing a command.Imgur

Theme engine

  • Built-in themes: Light, Dark, Mint, Strawberry, Ice, Sunny, Spruce, Cherry, Cave, Lunar
  • System mode — follows the OS light/dark preference automatically
  • Custom themes — create, edit, export, import, and persist your own color palettes via the built-in ThemeEditorWindow
  • Accent color follows the OS accent or can be overridden per-user; light/dark variants and gradient pairs are generated automatically
  • Settings are persisted to disk automatically on desktop; mobile apps can save manually

Localization system

  • Localizer singleton backed by .NET ResourceManager — add any number of .resx resource files
  • {Localize Key} AXAML markup extension binds reactively — switching language updates every bound string instantly without reloading views
  • Localizer.TrDefault(key, fallback) for safe lookups that fall back to a raw string instead of an error message
  • LocalizationChanged event for view models and code-behind to react to language switches
  • A localization key analyzer is included. You won't miss any unused keys in your applications!

Packages

PackageDescription
PleasantUICore theme, all control styles, Pleasant controls, theme engine, localization
PleasantUI.ToolKitMessageBox, ThemeEditorWindow, color picker utilities
PleasantUI.MaterialIconsMaterial Design icon geometry library for use with PathIcon
PleasantUI.DataGridFluent-styled DataGrid extension

📖 Documentation

Detailed reference docs for each control are in the docs/ folder:

DocControls
PleasantWindowPleasantWindow, IPleasantSplashScreen
PleasantMiniWindowPleasantMiniWindow
PleasantTitleBarPleasantTitleBar
PleasantCaptionButtonsPleasantCaptionButtons
NavigationViewNavigationView, NavigationViewItem
PleasantTabViewPleasantTabView, PleasantTabItem
ContentDialogContentDialog
MessageBoxMessageBox (ToolKit)
PleasantDialogPleasantDialog (ToolKit)
CrashReportDialogCrashReportDialog
StepDialogStepDialog
PleasantSnackbarPleasantSnackbar
ProgressRingProgressRing
OptionsDisplayItemOptionsDisplayItem
InformationBlockInformationBlock
TimelineTimeline, TimelineItem
InstallWizardInstallWizard, WizardStep
PathPickerPathPicker
PopConfirmPopConfirm
PleasantMenuPleasantMenu, PleasantMenuItem, PleasantMenuFooterItem
PleasantMenuFlyoutPleasantMenuFlyout
PleasantFlyoutPleasantFlyout
PinCodePinCode
SelectionListSelectionList, SelectionListItem
RippleEffectRippleEffect
SmoothScrollViewerSmoothScrollViewer
MarkedInputsMarkedTextBox, MarkedNumericUpDown
MarkedTextBoxMarkedTextBox
MarkedNumericUpDownMarkedNumericUpDown
PleasantDatePickerPleasantDatePicker
PleasantBorderPleasantBorder
BackdropBlurBorderBackdropBlurBorder
ShadowBorderShadowBorder
PleasantTrayPopupPleasantTrayPopup, StatusItem
DataGridPleasantUI.DataGrid package
PropertyGridPropertyGrid, PropertyRow
CommandBarCommandBar, CommandBarButton, CommandBarToggleButton
BreadcrumbBarBreadcrumbBar, BreadcrumbBarItem
PleasantDrawerPleasantDrawer
DashboardCardDashboardCard
DownloadPanelDownloadPanel
LogViewerPanelLogViewerPanel
TerminalPanelTerminalPanel
TreeViewPanelTreeViewPanel, TreeViewSection
ItemListPanelItemListPanel
VirtualizingWrapPanelVirtualizingWrapPanel
PleasantViewPleasantView
PleasantSplashScreenPleasantSplashScreen
ModalWindowHostModalWindowHost
ThemePreviewVariantScopeThemePreviewVariantScope
LocalizationLocalizer, {Localize} markup extension
Theme EnginePleasantTheme, custom themes, color tokens

🚀 Getting Started

Install

Package List (Avalonia 12)

Published on NuGet:

<PackageReferenceInclude="PleasantUI"Version="5.3.0" />
<PackageReferenceInclude="PleasantUI.DataGrid"Version="5.3.0" />
<PackageReferenceInclude="PleasantUI.MaterialIcons"Version="5.3.0" />
<PackageReferenceInclude="PleasantUI.ToolKit"Version="5.3.0" />

Add the theme

In your App.axaml, add PleasantTheme to your styles:

<Applicationxmlns="https://github.com/avaloniaui"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"x:Class="YourApp.App">
<Application.Styles>
<PleasantTheme />
</Application.Styles>
</Application>

Initialize correctly

Make sure AvaloniaXamlLoader.Load(this) is called in Initialize():

publicpartialclassApp:Application{publicoverridevoidInitialize(){AvaloniaXamlLoader.Load(this);// required}publicoverridevoidOnFrameworkInitializationCompleted(){if(ApplicationLifetimeisIClassicDesktopStyleApplicationLifetimedesktop){desktop.MainWindow=newMainWindow{DataContext=newMainWindowViewModel(),};}base.OnFrameworkInitializationCompleted();}}

Use PleasantWindow

Replace Window with PleasantWindow to get the custom Fluent title bar:

usingPleasantUI.Controls;publicpartialclassMainWindow:PleasantWindow{publicMainWindow()=>InitializeComponent();}
<PleasantWindowxmlns="https://github.com/avaloniaui"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"mc:Ignorable="d"d:DesignWidth="800"d:DesignHeight="450"x:Class="YourApp.Views.MainWindow"Title="Avalonia Application">
</PleasantWindow>

Key PleasantWindow properties:

PropertyTypeDescription
TitleBarTypeClassic / ClassicExtendedTitle bar layout style
ExtendsContentIntoTitleBarboolLets content render behind the title bar
SubtitlestringSecondary text shown next to the title
DisplayIconobjectCustom icon content in the title bar
DisplayTitleobjectCustom title content (e.g. a PathIcon)
EnableBlurboolAcrylic/blur window background
CaptionButtonsenumWhich caption buttons to show
LeftTitleBarContentobjectContent injected left of the title

🌍 Localization

Register your .resx resource managers in your Application constructor:

publicApp(){Localizer.AddRes(newResourceManager(typeof(Properties.Localizations.App)));Localizer.ChangeLang("en");}

Use {Localize Key} in AXAML — updates live when the language changes:

<TextBlockText="{Localize WelcomeMessage}" />
<ButtonContent="{Localize SaveButton}" />

Switch language at runtime:

Localizer.ChangeLang("ru");

Safe lookup with fallback in code-behind:

stringtitle=Localizer.TrDefault("DialogTitle","Confirm");

🔲 Button variants

<ButtonContent="Default" />
<ButtonTheme="{StaticResource AccentButtonTheme}"Content="Accent" />
<ButtonTheme="{StaticResource DangerButtonTheme}"Content="Danger" />
<ButtonTheme="{StaticResource AppBarButtonTheme}"Content="AppBar" />

📃 OptionsDisplayItem

<!-- Navigation row -->
<OptionsDisplayItemHeader="Account"Description="Manage your account"Icon="{x:Static MaterialIcons.AccountOutline}"Navigates="True" />
<!-- Row with action control -->
<OptionsDisplayItemHeader="Dark mode"Icon="{x:Static MaterialIcons.WeatherNight}">
<OptionsDisplayItem.ActionButton>
<ToggleSwitch />
</OptionsDisplayItem.ActionButton>
</OptionsDisplayItem>
<!-- Expandable row -->
<OptionsDisplayItemHeader="Advanced"Expands="True">
<OptionsDisplayItem.Content>
<StackPanel>
<CheckBoxContent="Enable feature X" />
</StackPanel>
</OptionsDisplayItem.Content>
</OptionsDisplayItem>

🖼️ Screenshots

Regul Save Cleaner

image

OlibKey

image

❤️ Credits

Main

Controls and Code

  • Aura.UI (PieroCastillo) - NavigationView and AuraTabView under license from MIT
  • ProgressRing (ymg2006) - under license from MIT
  • RichTextKit (toptensoftware) - implementation of BinarySearch under license from Apache 2.0
  • weather (rocksdanister) - implementation of BackdropBlurBorder under license from MIT
  • Xaml.Behaviors.Interactions.Animated (Egolds) - implementation of VerticalScrollViewerAnimatedBehavior under license from MIT
  • BilibiliClient (afunc233) - implementation of VirtualizingWrapPanel
  • Material.Avalonia (CommunityAvalonia) - implementation of Ripple Effect under license from MIT

Releases

Sponsor this project

Packages

Used by

Contributors

Languages