Skip to content
Draft
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
34010db
Add Avalonia.Themes.Fluent2: baseline copy of Avalonia.Themes.Fluent
MikeCodesDotNET Jul 13, 2026
c8e7782
Fluent2: add WinUI 3 token foundation
MikeCodesDotNET Jul 13, 2026
ad2390e
Fluent2: re-skin Button, TextBox and CheckBox to WinUI 3 (spike)
MikeCodesDotNET Jul 13, 2026
af73839
Fluent2: add compatibility audit tests and ControlCatalog integration
MikeCodesDotNET Jul 13, 2026
b75afd6
Fluent2: derive WinUI tokens from legacy palette colors
MikeCodesDotNET Jul 13, 2026
b0a786c
Fluent2: re-skin Phase A core input controls to WinUI 3
MikeCodesDotNET Jul 13, 2026
93125c1
Fluent2: re-skin Phase B lists, menus, popups and navigation to WinUI 3
MikeCodesDotNET Jul 13, 2026
0ac0dfb
Fluent2: re-skin Phase C pickers and calendar to WinUI 3
MikeCodesDotNET Jul 13, 2026
4c649b4
Fluent2: re-skin Phase D chrome, notifications and misc controls
MikeCodesDotNET Jul 13, 2026
62f6f62
Fluent2: add README with migration notes and compatibility contract
MikeCodesDotNET Jul 13, 2026
a71bbb5
Fluent2: paint window canvas via tree-anchored resource in template
MikeCodesDotNET Jul 13, 2026
afb28ec
Fixed the dark theme.
MikeCodesDotNET Jul 13, 2026
71bbc90
Fluent2: use OS accent shades on Windows, drop WinUI's forced MinWidth
MikeCodesDotNET Jul 13, 2026
e92aac7
Fluent2: animate selection pills via transforms, cross-fade Expander …
MikeCodesDotNET Jul 13, 2026
ac887aa
Fluent2: localize picker field names and text flyout labels for ~85 l…
MikeCodesDotNET Jul 13, 2026
94f7bc7
ControlCatalog: add dashboard home page with animated hero and nav cards
MikeCodesDotNET Jul 13, 2026
e83cff7
ControlCatalog: use the Accelerate demo hero banner verbatim on the h…
MikeCodesDotNET Jul 13, 2026
044910c
ControlCatalog: default to the Fluent2 theme
MikeCodesDotNET Jul 13, 2026
d898284
Updated
MikeCodesDotNET Jul 13, 2026
81ebe2b
Merge branch 'main' into themes/fluent2
maxkatz6 Aug 25, 2026
14b1bfa
DataGridPage was removed
maxkatz6 Aug 25, 2026
319b470
Merge remote-tracking branch 'origin/main' into themes/fluent2
maxkatz6 Aug 28, 2026
134817f
Revert "Fluent2: use OS accent shades on Windows"
maxkatz6 Aug 28, 2026
2d479fb
Merge branch 'main' into themes/fluent2
emmauss Sep 4, 2026
9776896
adjust nav bar appearance. make the bar transparent
emmauss Sep 4, 2026
ab2b895
button - add background transition
emmauss Sep 4, 2026
d994b14
buttonspinner - remove invalid grid property
emmauss Sep 4, 2026
f71d0b3
revert changes to old fluent button
emmauss Sep 7, 2026
17b8ffb
fluent2 - fix check glyph type and size
emmauss Sep 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Avalonia.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
<Project Path="tests/Avalonia.RenderTests.WpfCompare/Avalonia.RenderTests.WpfCompare.csproj" />
<Project Path="tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj" />
<Project Path="tests/Avalonia.Skia.UnitTests/Avalonia.Skia.UnitTests.csproj" />
<Project Path="tests/Avalonia.Themes.Fluent2.UnitTests/Avalonia.Themes.Fluent2.UnitTests.csproj" />
<Project Path="tests/Avalonia.UnitTests/Avalonia.UnitTests.csproj" />
</Folder>
<Folder Name="/Tests/TestFiles/" />
Expand All @@ -155,6 +156,7 @@
</Folder>
<Folder Name="/Themes/">
<Project Path="src/Avalonia.Themes.Fluent/Avalonia.Themes.Fluent.csproj" />
<Project Path="src/Avalonia.Themes.Fluent2/Avalonia.Themes.Fluent2.csproj" />
<Project Path="src/Avalonia.Themes.Simple/Avalonia.Themes.Simple.csproj" />
</Folder>
<Folder Name="/Tools/">
Expand Down
1 change: 1 addition & 0 deletions nukebuild/Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ DotNetRunSettings ApplySetting(DotNetRunSettings settings, string project, strin
RunCoreTest("Avalonia.Headless.NUnit.PerTest.UnitTests");
RunCoreTest("Avalonia.Headless.XUnit.PerAssembly.UnitTests");
RunCoreTest("Avalonia.Headless.XUnit.PerTest.UnitTests");
RunCoreTest("Avalonia.Themes.Fluent2.UnitTests");
});

Target RunRenderTests => _ => _
Expand Down
1 change: 1 addition & 0 deletions samples/ControlCatalog/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

<!-- Styles attached dynamically depending on current theme (simple or fluent) -->
<FluentTheme x:Key="FluentTheme" />
<Fluent2Theme x:Key="Fluent2Theme" />
<SimpleTheme x:Key="SimpleTheme" />
<StyleInclude x:Key="ColorPickerFluent" Source="avares://Avalonia.Controls.ColorPicker/Themes/Fluent/Fluent.xaml" />
<StyleInclude x:Key="ColorPickerSimple" Source="avares://Avalonia.Controls.ColorPicker/Themes/Simple/Simple.xaml" />
Expand Down
9 changes: 8 additions & 1 deletion samples/ControlCatalog/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class App : Application
{
private readonly Styles _themeStylesContainer = new();
private FluentTheme? _fluentTheme;
private Avalonia.Themes.Fluent2.Fluent2Theme? _fluent2Theme;
private SimpleTheme? _simpleTheme;
private IStyle? _colorPickerFluent, _colorPickerSimple;

Expand All @@ -31,11 +32,12 @@ public override void Initialize()
AvaloniaXamlLoader.Load(this);

_fluentTheme = (FluentTheme)Resources["FluentTheme"]!;
_fluent2Theme = (Avalonia.Themes.Fluent2.Fluent2Theme)Resources["Fluent2Theme"]!;
_simpleTheme = (SimpleTheme)Resources["SimpleTheme"]!;
_colorPickerFluent = (IStyle)Resources["ColorPickerFluent"]!;
_colorPickerSimple = (IStyle)Resources["ColorPickerSimple"]!;

SetCatalogThemes(CatalogTheme.Fluent);
SetCatalogThemes(CatalogTheme.Fluent2);
}

public override void OnFrameworkInitializationCompleted()
Expand Down Expand Up @@ -125,6 +127,11 @@ public static void SetCatalogThemes(CatalogTheme theme)
app._themeStylesContainer[0] = app._fluentTheme!;
app._themeStylesContainer[1] = app._colorPickerFluent!;
}
else if (theme == CatalogTheme.Fluent2)
{
app._themeStylesContainer[0] = app._fluent2Theme!;
app._themeStylesContainer[1] = app._colorPickerFluent!;
}
else if (theme == CatalogTheme.Simple)
{
app._themeStylesContainer[0] = app._simpleTheme!;
Expand Down
Binary file modified samples/ControlCatalog/Assets/Icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/ControlCatalog/Assets/banner-bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/ControlCatalog/Assets/banner-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/ControlCatalog/Assets/logo1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/ControlCatalog/Assets/logo2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/ControlCatalog/Assets/logo3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/ControlCatalog/Assets/logo4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions samples/ControlCatalog/ControlCatalog.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
<ProjectReference Include="..\..\src\Avalonia.Controls.ColorPicker\Avalonia.Controls.ColorPicker.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Simple\Avalonia.Themes.Simple.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Fluent\Avalonia.Themes.Fluent.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Fluent2\Avalonia.Themes.Fluent2.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Fonts.Inter\Avalonia.Fonts.Inter.csproj" />
<ProjectReference Include="..\..\src\Skia\Avalonia.Skia\Avalonia.Skia.csproj" />
<ProjectReference Include="..\MiniMvvm\MiniMvvm.csproj" />
Expand Down
3 changes: 3 additions & 0 deletions samples/ControlCatalog/Icons.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,5 +190,8 @@ internal static class Icons

// Slider tune/adjust
public const string Tune = "M3,17V19H9V17H3M3,5V7H13V5H3M13,21V19H21V17H13V15H11V21H13M7,9V11H3V13H7V15H9V9H7M21,13V11H11V13H21M15,9H17V7H21V5H17V3H15V9Z";

// Home
public const string Home = "M10,20V14H14V20H19V12H22L12,3L2,12H5V20H10Z";
}
}
1 change: 1 addition & 0 deletions samples/ControlCatalog/MainView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
ToolTip.Tip="Catalog Theme">
<ComboBox.Items>
<models:CatalogTheme>Fluent</models:CatalogTheme>
<models:CatalogTheme>Fluent2</models:CatalogTheme>
<models:CatalogTheme>Simple</models:CatalogTheme>
</ComboBox.Items>
</ComboBox>
Expand Down
1 change: 1 addition & 0 deletions samples/ControlCatalog/Models/CatalogTheme.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
public enum CatalogTheme
{
Fluent,
Fluent2,
Simple
}
}
163 changes: 163 additions & 0 deletions samples/ControlCatalog/Pages/HomePage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<ContentPage Theme="{StaticResource ScrollPage}"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModels="using:ControlCatalog.ViewModels"
x:Class="ControlCatalog.Pages.HomePage"
x:DataType="viewModels:MainWindowViewModel"
Header="Home">

<ContentPage.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default">
<SolidColorBrush x:Key="HomeCardBackground" Color="#FFFFFF" />
<SolidColorBrush x:Key="HomeCardBorderBrush" Color="#E5E5EA" />
<SolidColorBrush x:Key="HomeCardBorderBrushHover" Color="#3E6DF3" />
<SolidColorBrush x:Key="HomeSubtleForeground" Color="#64646E" />
<SolidColorBrush x:Key="HomeBadgeBackground" Color="#E8EFFD" />
<SolidColorBrush x:Key="HomeBadgeForeground" Color="#3462D9" />
<SolidColorBrush x:Key="HomeSectionDivider" Color="#EBEBEF" />
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="HomeCardBackground" Color="#2B2B33" />
<SolidColorBrush x:Key="HomeCardBorderBrush" Color="#3A3A45" />
<SolidColorBrush x:Key="HomeCardBorderBrushHover" Color="#8AB4FF" />
<SolidColorBrush x:Key="HomeSubtleForeground" Color="#9C9CAB" />
<SolidColorBrush x:Key="HomeBadgeBackground" Color="#31395A" />
<SolidColorBrush x:Key="HomeBadgeForeground" Color="#8AB4FF" />
<SolidColorBrush x:Key="HomeSectionDivider" Color="#3A3A45" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</ContentPage.Resources>

<ContentPage.Styles>
<!-- Neutralize the themed Button chrome so only the inner card Border shows. -->
<Style Selector="Button.card /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
</Style>
<Style Selector="Button.card:pointerover /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
</Style>
<Style Selector="Button.card:pressed /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
</Style>
<Style Selector="Button.card > Border">
<Setter Property="Transitions">
<Transitions>
<BrushTransition Property="BorderBrush" Duration="0:0:0.1" />
</Transitions>
</Setter>
</Style>
<Style Selector="Button.card:pointerover > Border">
<Setter Property="BorderBrush" Value="{DynamicResource HomeCardBorderBrushHover}" />
</Style>
</ContentPage.Styles>

<StackPanel Spacing="28" Margin="0,0,15,20" HorizontalAlignment="Stretch">

<!-- Hero banner (1:1 from the Accelerate demo dashboard) -->
<Border CornerRadius="20" ClipToBounds="True" HorizontalAlignment="Stretch" Height="220">
<Grid ClipToBounds="True">
<Image Source="/Assets/banner-bg.png"
Stretch="UniformToFill" />
<Canvas IsHitTestVisible="False">
<Image x:Name="BannerLogo1"
Source="/Assets/logo1.png"
Width="230"
Stretch="Uniform"
Canvas.Left="-60"
Canvas.Bottom="-50" />
<Image x:Name="BannerLogo2"
Source="/Assets/logo2.png"
Width="150"
Stretch="Uniform"
Canvas.Left="240"
Canvas.Top="-60" />
<Image x:Name="BannerLogo3"
Source="/Assets/logo3.png"
Width="210"
Stretch="Uniform"
Canvas.Right="-70"
Canvas.Top="-50" />
<Image x:Name="BannerLogo4"
Source="/Assets/logo4.png"
Width="170"
Stretch="Uniform"
Canvas.Right="40"
Canvas.Bottom="-60" />
</Canvas>
<Image Source="/Assets/banner-logo.png"
Width="220"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</Border>

<!-- Card sections -->
<ItemsControl ItemsSource="{Binding HomeSections}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="viewModels:HomeSection">
<StackPanel Spacing="14" Margin="0,0,0,26">
<TextBlock Text="{Binding Title}"
FontSize="19" FontWeight="Bold" />
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="viewModels:PageItem">
<Button Classes="card"
Command="{Binding $parent[ContentPage].((viewModels:MainWindowViewModel)DataContext).NavigateToPageCommand}"
CommandParameter="{Binding}"
Margin="0,0,12,12"
Padding="0"
Background="Transparent"
BorderThickness="0"
Cursor="Hand">
<Border Background="{DynamicResource HomeCardBackground}"
BorderBrush="{DynamicResource HomeCardBorderBrush}"
BorderThickness="1"
CornerRadius="10"
Padding="16,14"
Width="248"
MinHeight="118"
BoxShadow="0 1 3 0 #0D000000">
<StackPanel Spacing="10">
<Border Background="{DynamicResource HomeBadgeBackground}"
CornerRadius="8"
Width="36" Height="36"
HorizontalAlignment="Left">
<PathIcon Data="{Binding IconData}"
Foreground="{DynamicResource HomeBadgeForeground}"
Width="18" Height="18"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
<StackPanel Spacing="3">
<TextBlock Text="{Binding Header}"
FontSize="14" FontWeight="SemiBold" />
<TextBlock Text="{Binding Description}"
FontSize="12"
Foreground="{DynamicResource HomeSubtleForeground}"
TextWrapping="Wrap"
MaxLines="2" />
</StackPanel>
</StackPanel>
</Border>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

</StackPanel>
</ContentPage>
78 changes: 78 additions & 0 deletions samples/ControlCatalog/Pages/HomePage.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using System;
using Avalonia;
using Avalonia.Animation;
using Avalonia.Controls;
using Avalonia.Media;
using Avalonia.Styling;
using Avalonia.VisualTree;
using ControlCatalog.ViewModels;

namespace ControlCatalog.Pages
{
public partial class HomePage : ContentPage
{
public HomePage()
{
InitializeComponent();
}

protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);

// Pages hosted in a NavigationPage inherit the navigator as DataContext;
// the card grid binds to MainWindowViewModel, so resolve it from MainView.
if (DataContext is not MainWindowViewModel)
DataContext = this.FindAncestorOfType<MainView>()?.DataContext;

StartFloatingAnimation(BannerLogo1, 12, 8, TimeSpan.FromSeconds(12));
StartFloatingAnimation(BannerLogo2, -14, 8, TimeSpan.FromSeconds(10));
StartFloatingAnimation(BannerLogo3, -12, -12, TimeSpan.FromSeconds(14));
StartFloatingAnimation(BannerLogo4, 12, -8, TimeSpan.FromSeconds(11));
}

private static void StartFloatingAnimation(Control target, double dx, double dy, TimeSpan duration)
{
var transform = new TranslateTransform();
target.RenderTransform = transform;

var animation = new Animation
{
Duration = duration,
IterationCount = IterationCount.Infinite,
Children =
{
new KeyFrame
{
Cue = new Cue(0d),
Setters =
{
new Setter(TranslateTransform.XProperty, 0d),
new Setter(TranslateTransform.YProperty, 0d),
}
},
new KeyFrame
{
Cue = new Cue(0.5d),
Setters =
{
new Setter(TranslateTransform.XProperty, dx),
new Setter(TranslateTransform.YProperty, dy),
}
},
new KeyFrame
{
Cue = new Cue(1d),
Setters =
{
new Setter(TranslateTransform.XProperty, 0d),
new Setter(TranslateTransform.YProperty, 0d),
}
},
}
};

_ = animation.RunAsync(target);
}
}
}
3 changes: 3 additions & 0 deletions samples/ControlCatalog/ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public MainWindowViewModel()
{
(App.Current?.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime)?.Shutdown();
});
NavigateToPageCommand = MiniCommand.Create<PageItem>(NavigateToPage);

WindowState = WindowState.Normal;

Expand Down Expand Up @@ -127,6 +128,8 @@ public int SelectedDecorationIndex

public MiniCommand ExitCommand { get; }

public MiniCommand NavigateToPageCommand { get; }

private DateTime? _validatedDateExample;

/// <summary>
Expand Down
Loading