Browse Source

Fluent2: re-skin Phase D chrome, notifications and misc controls

- Window/EmbeddableControlRoot: SolidBackgroundFillColorBase canvas
- WindowDrawnDecorations: Windows 11 caption buttons (46x32, subtle fills,
  red close hover #C42B1C with white glyph), 10px glyphs, hairline frame
- NotificationCard as WinUI InfoBar: r4 card, severity background tints +
  16px severity badges, subtle close button; notification manager spacing
- CommandBar: transparent rest / acrylic-fallback open state per WinUI,
  AppBarButton subtle pills with accent-checked toggles, WinUI separators
- Mobile pages: SolidBackgroundFillColorBaseAlt bars with dividers, 40px
  subtle back button, SmokeFillColorDefault drawer scrim, 3px accent tab
  indicator; TextSelectionHandle accent recolor
- Label/HeaderedContentControl typography; GroupBox converted to the card
  idiom; GridSplitter subtle hover; RefreshVisualizer accent spinner
- ManagedFileChooser re-tokened (layer sidebar, divider rules)
- Compact density re-derived against WinUI 3 base metrics; adds
  ListBoxItemMinHeight 24 so compact lists actually shrink

All 8 audit tests green; verified light+dark headless renders.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pull/21771/head
Mike James 3 months ago
parent
commit
4c649b479f
  1. 24
      src/Avalonia.Themes.Fluent2/Accents/FluentControlResources.xaml
  2. 2
      src/Avalonia.Themes.Fluent2/Controls/CarouselPage.xaml
  3. 207
      src/Avalonia.Themes.Fluent2/Controls/CommandBar.xaml
  4. 4
      src/Avalonia.Themes.Fluent2/Controls/ContentPage.xaml
  5. 14
      src/Avalonia.Themes.Fluent2/Controls/DrawerPage.xaml
  6. 2
      src/Avalonia.Themes.Fluent2/Controls/EmbeddableControlRoot.xaml
  7. 28
      src/Avalonia.Themes.Fluent2/Controls/GridSplitter.xaml
  8. 81
      src/Avalonia.Themes.Fluent2/Controls/GroupBox.xaml
  9. 16
      src/Avalonia.Themes.Fluent2/Controls/HeaderedContentControl.xaml
  10. 15
      src/Avalonia.Themes.Fluent2/Controls/Label.xaml
  11. 29
      src/Avalonia.Themes.Fluent2/Controls/ManagedFileChooser.xaml
  12. 27
      src/Avalonia.Themes.Fluent2/Controls/NavigationPage.xaml
  13. 159
      src/Avalonia.Themes.Fluent2/Controls/NotificationCard.xaml
  14. 8
      src/Avalonia.Themes.Fluent2/Controls/RefreshContainer.xaml
  15. 7
      src/Avalonia.Themes.Fluent2/Controls/RefreshVisualizer.xaml
  16. 45
      src/Avalonia.Themes.Fluent2/Controls/TabbedPage.xaml
  17. 10
      src/Avalonia.Themes.Fluent2/Controls/TextSelectionHandle.xaml
  18. 5
      src/Avalonia.Themes.Fluent2/Controls/Window.xaml
  19. 95
      src/Avalonia.Themes.Fluent2/Controls/WindowDrawnDecorations.xaml
  20. 30
      src/Avalonia.Themes.Fluent2/Controls/WindowNotificationManager.xaml
  21. 20
      src/Avalonia.Themes.Fluent2/DensityStyles/Compact.xaml

24
src/Avalonia.Themes.Fluent2/Accents/FluentControlResources.xaml

@ -84,7 +84,7 @@
<StaticResource x:Key="ToggleButtonBorderBrushIndeterminateDisabled" ResourceKey="ControlStrokeColorDefaultBrush" />
<!-- GroupBox -->
<Thickness x:Key="GroupBoxPadding">4</Thickness>
<Thickness x:Key="GroupBoxPadding">12</Thickness>
<x:Double x:Key="GroupBoxHeaderFontSize">16</x:Double>
<Thickness x:Key="GroupBoxHeaderMargin">0,4,0,12</Thickness>
<Thickness x:Key="GroupBoxBorderThickness">1</Thickness>
@ -383,12 +383,12 @@
<!--Resources for NotificationCard.xaml -->
<SolidColorBrush x:Key="NotificationCardBackgroundBrush" Color="White" />
<StaticResource x:Key="NotificationCardForegroundBrush" ResourceKey="SystemControlForegroundBaseHighBrush" />
<StaticResource x:Key="NotificationCardForegroundBrush" ResourceKey="TextFillColorPrimaryBrush" />
<SolidColorBrush x:Key="NotificationCardProgressBackgroundBrush" Color="#9A9A9A" />
<SolidColorBrush x:Key="NotificationCardInformationBackgroundBrush" Color="#0078D4" />
<SolidColorBrush x:Key="NotificationCardSuccessBackgroundBrush" Color="#128B44" />
<SolidColorBrush x:Key="NotificationCardWarningBackgroundBrush" Color="#FFC316" />
<SolidColorBrush x:Key="NotificationCardErrorBackgroundBrush" Color="#F03916" />
<StaticResource x:Key="NotificationCardInformationBackgroundBrush" ResourceKey="SystemFillColorAttentionBackgroundBrush" />
<StaticResource x:Key="NotificationCardSuccessBackgroundBrush" ResourceKey="SystemFillColorSuccessBackgroundBrush" />
<StaticResource x:Key="NotificationCardWarningBackgroundBrush" ResourceKey="SystemFillColorCautionBackgroundBrush" />
<StaticResource x:Key="NotificationCardErrorBackgroundBrush" ResourceKey="SystemFillColorCriticalBackgroundBrush" />
<!-- Resources for RadioButton.xaml -->
<x:Double x:Key="RadioButtonBorderThemeThickness">1</x:Double>
@ -774,7 +774,7 @@
<StaticResource x:Key="ToggleButtonBorderBrushIndeterminateDisabled" ResourceKey="ControlStrokeColorDefaultBrush" />
<!-- GroupBox -->
<Thickness x:Key="GroupBoxPadding">4</Thickness>
<Thickness x:Key="GroupBoxPadding">12</Thickness>
<x:Double x:Key="GroupBoxHeaderFontSize">16</x:Double>
<Thickness x:Key="GroupBoxHeaderMargin">0,4,0,12</Thickness>
<Thickness x:Key="GroupBoxBorderThickness">1</Thickness>
@ -1074,12 +1074,12 @@
<!--Resources for NotificationCard.xaml -->
<SolidColorBrush x:Key="NotificationCardBackgroundBrush" Color="#444444" />
<StaticResource x:Key="NotificationCardForegroundBrush" ResourceKey="SystemControlForegroundBaseHighBrush" />
<StaticResource x:Key="NotificationCardForegroundBrush" ResourceKey="TextFillColorPrimaryBrush" />
<SolidColorBrush x:Key="NotificationCardProgressBackgroundBrush" Color="#9A9A9A" />
<SolidColorBrush x:Key="NotificationCardInformationBackgroundBrush" Color="#007ACC" Opacity="0.75" />
<SolidColorBrush x:Key="NotificationCardSuccessBackgroundBrush" Color="#1F9E45" Opacity="0.75" />
<SolidColorBrush x:Key="NotificationCardWarningBackgroundBrush" Color="#FDB328" Opacity="0.75" />
<SolidColorBrush x:Key="NotificationCardErrorBackgroundBrush" Color="#BD202C" Opacity="0.75" />
<StaticResource x:Key="NotificationCardInformationBackgroundBrush" ResourceKey="SystemFillColorAttentionBackgroundBrush" />
<StaticResource x:Key="NotificationCardSuccessBackgroundBrush" ResourceKey="SystemFillColorSuccessBackgroundBrush" />
<StaticResource x:Key="NotificationCardWarningBackgroundBrush" ResourceKey="SystemFillColorCautionBackgroundBrush" />
<StaticResource x:Key="NotificationCardErrorBackgroundBrush" ResourceKey="SystemFillColorCriticalBackgroundBrush" />
<!-- Resources for RadioButton.xaml -->
<x:Double x:Key="RadioButtonBorderThemeThickness">1</x:Double>

2
src/Avalonia.Themes.Fluent2/Controls/CarouselPage.xaml

@ -14,7 +14,7 @@
</Design.PreviewWith>
<ControlTheme x:Key="{x:Type CarouselPage}" TargetType="CarouselPage">
<Setter Property="Background" Value="{DynamicResource SystemControlPageBackgroundAltHighBrush}" />
<Setter Property="Background" Value="{DynamicResource SolidBackgroundFillColorBaseBrush}" />
<Setter Property="Template">
<ControlTemplate>
<Carousel Name="PART_Carousel"

207
src/Avalonia.Themes.Fluent2/Controls/CommandBar.xaml

@ -26,24 +26,92 @@
</Border>
</Design.PreviewWith>
<!-- CommandBarButton ControlTheme -->
<!-- WinUI reference: CommandBar_themeresources.xaml, AppBarButton_themeresources.xaml (winui3/release/1.6.4),
AppBarToggleButton_themeresources.xaml, AppBarSeparator_themeresources.xaml (via Uno.UI.FluentTheme.v2).
AppBar idiom: transparent bar (CommandBarBackground = ControlFillColorTransparent; the open state uses
AcrylicInAppFillColorDefault with a 1px CardStrokeColorDefaultSolid border), subtle-fill command pills
with ControlCornerRadius and an 83ms fill cross-fade, 16px icons (AppBarButtonContentHeight) with 12px
labels, checked toggles on AccentFillColorDefault with TextOnAccent text, and 1px
DividerStrokeColorDefault separators (AppBarSeparatorMargin 2,8). WinUI's default closed CommandBar has
no bottom divider, so none is drawn here. The v1 SystemControl* brush references were re-pointed to the
Fluent 2 tokens in this file; no shared-file keys are defined for these controls. -->
<!-- CommandBar ellipsis (more) button: same subtle-fill treatment as AppBarButton. -->
<ControlTheme x:Key="Fluent2CommandBarMoreButtonTheme" TargetType="Button">
<Setter Property="Background" Value="{DynamicResource SubtleFillColorTransparentBrush}" />
<Setter Property="BackgroundSizing" Value="InnerBorderEdge" />
<Setter Property="Foreground" Value="{DynamicResource TextFillColorPrimaryBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource ControlFillColorTransparentBrush}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<ControlTemplate>
<ContentPresenter x:Name="PART_ContentPresenter"
Background="{TemplateBinding Background}"
BackgroundSizing="{TemplateBinding BackgroundSizing}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Padding="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
<ContentPresenter.Transitions>
<Transitions>
<BrushTransition Property="Background" Duration="0:0:0.083" />
</Transitions>
</ContentPresenter.Transitions>
</ContentPresenter>
</ControlTemplate>
</Setter>
<Style Selector="^:pointerover /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="{DynamicResource SubtleFillColorSecondaryBrush}" />
</Style>
<Style Selector="^:pressed /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="{DynamicResource SubtleFillColorTertiaryBrush}" />
</Style>
<Style Selector="^:pressed">
<Setter Property="Foreground" Value="{DynamicResource TextFillColorSecondaryBrush}" />
</Style>
<Style Selector="^:disabled /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="{DynamicResource SubtleFillColorDisabledBrush}" />
</Style>
<Style Selector="^:disabled">
<Setter Property="Foreground" Value="{DynamicResource TextFillColorDisabledBrush}" />
</Style>
</ControlTheme>
<!-- CommandBarButton ControlTheme (WinUI DefaultAppBarButtonStyle) -->
<ControlTheme x:Key="{x:Type CommandBarButton}" TargetType="CommandBarButton">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Background" Value="{DynamicResource SubtleFillColorTransparentBrush}" />
<Setter Property="Foreground" Value="{DynamicResource TextFillColorPrimaryBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource ControlFillColorTransparentBrush}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="Padding" Value="8,4" />
<Setter Property="Width" Value="68" />
<Setter Property="MinHeight" Value="40" />
<Setter Property="MinHeight" Value="36" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<ControlTemplate>
<Border x:Name="PART_Border"
Background="{TemplateBinding Background}"
BackgroundSizing="InnerBorderEdge"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Padding="{TemplateBinding Padding}">
<Border.Transitions>
<Transitions>
<BrushTransition Property="Background" Duration="0:0:0.083" />
</Transitions>
</Border.Transitions>
<StackPanel x:Name="PART_LayoutRoot"
Spacing="4"
HorizontalAlignment="Center"
@ -51,11 +119,13 @@
<ContentPresenter x:Name="PART_IconPresenter"
Content="{TemplateBinding Icon}"
Foreground="{TemplateBinding Foreground}"
Width="16"
Height="16"
HorizontalAlignment="Center" />
<TextBlock x:Name="PART_Label"
Text="{TemplateBinding Label}"
Foreground="{TemplateBinding Foreground}"
FontSize="11"
FontSize="12"
HorizontalAlignment="Center"
TextTrimming="CharacterEllipsis" />
</StackPanel>
@ -65,12 +135,23 @@
<!-- Hover -->
<Style Selector="^:pointerover /template/ Border#PART_Border">
<Setter Property="Background" Value="{DynamicResource SystemControlHighlightListLowBrush}" />
<Setter Property="Background" Value="{DynamicResource SubtleFillColorSecondaryBrush}" />
</Style>
<!-- Pressed -->
<Style Selector="^:pressed /template/ Border#PART_Border">
<Setter Property="Background" Value="{DynamicResource SystemControlHighlightListMediumBrush}" />
<Setter Property="Background" Value="{DynamicResource SubtleFillColorTertiaryBrush}" />
</Style>
<Style Selector="^:pressed">
<Setter Property="Foreground" Value="{DynamicResource TextFillColorSecondaryBrush}" />
</Style>
<!-- Disabled -->
<Style Selector="^:disabled /template/ Border#PART_Border">
<Setter Property="Background" Value="{DynamicResource SubtleFillColorDisabledBrush}" />
</Style>
<Style Selector="^:disabled">
<Setter Property="Foreground" Value="{DynamicResource TextFillColorDisabledBrush}" />
</Style>
<!-- Compact: hide label, reduce width -->
@ -122,24 +203,33 @@
</Style>
</ControlTheme>
<!-- CommandBarToggleButton ControlTheme -->
<!-- CommandBarToggleButton ControlTheme (WinUI DefaultAppBarToggleButtonStyle) -->
<ControlTheme x:Key="{x:Type CommandBarToggleButton}" TargetType="CommandBarToggleButton">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Background" Value="{DynamicResource SubtleFillColorTransparentBrush}" />
<Setter Property="Foreground" Value="{DynamicResource TextFillColorPrimaryBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource ControlFillColorTransparentBrush}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="Padding" Value="8,4" />
<Setter Property="Width" Value="68" />
<Setter Property="MinHeight" Value="40" />
<Setter Property="MinHeight" Value="36" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<ControlTemplate>
<Border x:Name="PART_Border"
Background="{TemplateBinding Background}"
BackgroundSizing="InnerBorderEdge"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Padding="{TemplateBinding Padding}">
<Border.Transitions>
<Transitions>
<BrushTransition Property="Background" Duration="0:0:0.083" />
</Transitions>
</Border.Transitions>
<StackPanel x:Name="PART_LayoutRoot"
Spacing="4"
HorizontalAlignment="Center"
@ -147,11 +237,13 @@
<ContentPresenter x:Name="PART_IconPresenter"
Content="{TemplateBinding Icon}"
Foreground="{TemplateBinding Foreground}"
Width="16"
Height="16"
HorizontalAlignment="Center" />
<TextBlock x:Name="PART_Label"
Text="{TemplateBinding Label}"
Foreground="{TemplateBinding Foreground}"
FontSize="11"
FontSize="12"
HorizontalAlignment="Center"
TextTrimming="CharacterEllipsis" />
</StackPanel>
@ -161,17 +253,46 @@
<!-- Hover -->
<Style Selector="^:pointerover /template/ Border#PART_Border">
<Setter Property="Background" Value="{DynamicResource SystemControlHighlightListLowBrush}" />
<Setter Property="Background" Value="{DynamicResource SubtleFillColorSecondaryBrush}" />
</Style>
<!-- Pressed -->
<Style Selector="^:pressed /template/ Border#PART_Border">
<Setter Property="Background" Value="{DynamicResource SystemControlHighlightListMediumBrush}" />
<Setter Property="Background" Value="{DynamicResource SubtleFillColorTertiaryBrush}" />
</Style>
<Style Selector="^:pressed">
<Setter Property="Foreground" Value="{DynamicResource TextFillColorSecondaryBrush}" />
</Style>
<!-- Checked -->
<!-- Disabled -->
<Style Selector="^:disabled /template/ Border#PART_Border">
<Setter Property="Background" Value="{DynamicResource SubtleFillColorDisabledBrush}" />
</Style>
<Style Selector="^:disabled">
<Setter Property="Foreground" Value="{DynamicResource TextFillColorDisabledBrush}" />
</Style>
<!-- Checked: accent fill with on-accent text, per AppBarToggleButton_themeresources -->
<Style Selector="^:checked /template/ Border#PART_Border">
<Setter Property="Background" Value="{DynamicResource SystemControlHighlightAccentBrush}" />
<Setter Property="Background" Value="{DynamicResource AccentFillColorDefaultBrush}" />
</Style>
<Style Selector="^:checked">
<Setter Property="Foreground" Value="{DynamicResource TextOnAccentFillColorPrimaryBrush}" />
</Style>
<Style Selector="^:checked:pointerover /template/ Border#PART_Border">
<Setter Property="Background" Value="{DynamicResource AccentFillColorSecondaryBrush}" />
</Style>
<Style Selector="^:checked:pressed /template/ Border#PART_Border">
<Setter Property="Background" Value="{DynamicResource AccentFillColorTertiaryBrush}" />
</Style>
<Style Selector="^:checked:pressed">
<Setter Property="Foreground" Value="{DynamicResource TextOnAccentFillColorSecondaryBrush}" />
</Style>
<Style Selector="^:checked:disabled /template/ Border#PART_Border">
<Setter Property="Background" Value="{DynamicResource AccentFillColorDisabledBrush}" />
</Style>
<Style Selector="^:checked:disabled">
<Setter Property="Foreground" Value="{DynamicResource TextOnAccentFillColorDisabledBrush}" />
</Style>
<!-- Compact: hide label, reduce width -->
@ -223,34 +344,42 @@
</Style>
</ControlTheme>
<!-- CommandBarSeparator ControlTheme -->
<!-- CommandBarSeparator ControlTheme (WinUI DefaultAppBarSeparatorStyle:
1px DividerStrokeColorDefault, AppBarSeparatorMargin 2,8, corner radius 0.5) -->
<ControlTheme x:Key="{x:Type CommandBarSeparator}" TargetType="CommandBarSeparator">
<Setter Property="Width" Value="1" />
<Setter Property="MinHeight" Value="24" />
<Setter Property="Margin" Value="8,4" />
<Setter Property="Margin" Value="2,8" />
<Setter Property="Template">
<ControlTemplate>
<Border Background="{DynamicResource SystemControlForegroundBaseMediumLowBrush}"
<Border Background="{DynamicResource DividerStrokeColorDefaultBrush}"
CornerRadius="0.5"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
MinHeight="{TemplateBinding MinHeight}" />
</ControlTemplate>
</Setter>
<!-- IsInOverflow: horizontal separator -->
<!-- IsInOverflow: horizontal separator (AppBarOverflowSeparatorMargin 0,4) -->
<Style Selector="^[IsInOverflow=True]">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Width" Value="NaN" />
<Setter Property="Height" Value="1" />
<Setter Property="MinHeight" Value="0" />
<Setter Property="Margin" Value="4,4" />
<Setter Property="Margin" Value="0,4" />
</Style>
</ControlTheme>
<!-- CommandBar ControlTheme -->
<!-- CommandBar ControlTheme (WinUI XamlDefaultCommandBar) -->
<ControlTheme x:Key="{x:Type CommandBar}" TargetType="CommandBar">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Background" Value="{DynamicResource SystemControlBackgroundChromeMediumBrush}" />
<!-- CommandBarBackground = ControlFillColorTransparentBrush; the open state swaps to
AcrylicInAppFillColorDefault with a CardStrokeColorDefaultSolid border (see IsOpen style). -->
<Setter Property="Background" Value="{DynamicResource ControlFillColorTransparentBrush}" />
<Setter Property="Foreground" Value="{DynamicResource TextFillColorPrimaryBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource ControlFillColorTransparentBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="MinHeight" Value="48" />
<Setter Property="Padding" Value="4,0" />
<Setter Property="ItemWidthBottom" Value="70" />
@ -258,26 +387,33 @@
<Setter Property="ItemWidthCollapsed" Value="42" />
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}"
<Border x:Name="LayoutRoot"
Background="{TemplateBinding Background}"
BackgroundSizing="InnerBorderEdge"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Padding="{TemplateBinding Padding}"
MinHeight="{TemplateBinding MinHeight}">
<Border.Transitions>
<Transitions>
<BrushTransition Property="Background" Duration="0:0:0.083" />
<BrushTransition Property="BorderBrush" Duration="0:0:0.083" />
</Transitions>
</Border.Transitions>
<Panel>
<DockPanel KeyboardNavigation.TabNavigation="Cycle">
<!-- Overflow button (docked right) -->
<!-- Overflow (more/ellipsis) button (docked right) -->
<Button x:Name="PART_OverflowButton"
DockPanel.Dock="Right"
Background="Transparent"
BorderThickness="0"
Theme="{StaticResource Fluent2CommandBarMoreButtonTheme}"
Margin="2,6"
Padding="12,0"
MinWidth="40"
VerticalAlignment="Stretch"
FontSize="16"
IsVisible="{TemplateBinding IsOverflowButtonVisible}">
<PathIcon Width="16" Height="16"
Foreground="{TemplateBinding Foreground}"
Data="M6,10A2,2 0 0,0 4,12A2,2 0 0,0 6,14A2,2 0 0,0 8,12A2,2 0 0,0 6,10M12,10A2,2 0 0,0 10,12A2,2 0 0,0 12,14A2,2 0 0,0 14,12A2,2 0 0,0 12,10M18,10A2,2 0 0,0 16,12A2,2 0 0,0 18,14A2,2 0 0,0 20,12A2,2 0 0,0 18,10Z" />
</Button>
@ -301,15 +437,17 @@
</ItemsControl>
</DockPanel>
<!-- Overflow popup -->
<!-- Overflow popup (WinUI overflow presenter: AcrylicInAppFillColorDefault surface,
SurfaceStrokeColorFlyout 1px border, OverlayCornerRadius, min width 160) -->
<Popup x:Name="PART_OverflowPopup"
IsOpen="{TemplateBinding IsOpen, Mode=TwoWay}"
PlacementTarget="{Binding #PART_OverflowButton}"
Placement="Bottom"
IsLightDismissEnabled="True"
WindowManagerAddShadowHint="True">
<Border Background="{DynamicResource SystemControlBackgroundChromeMediumLowBrush}"
BorderBrush="{DynamicResource SystemControlForegroundBaseMediumLowBrush}"
<Border Background="{DynamicResource AcrylicInAppFillColorDefaultBrush}"
BackgroundSizing="InnerBorderEdge"
BorderBrush="{DynamicResource SurfaceStrokeColorFlyoutBrush}"
BorderThickness="1"
CornerRadius="{DynamicResource OverlayCornerRadius}"
Padding="4"
@ -328,5 +466,12 @@
</Border>
</ControlTemplate>
</Setter>
<!-- Open state: CommandBarBackgroundOpen / CommandBarBorderBrushOpen (thickness stays 1 to avoid
a layout jump; the rest-state border is transparent). -->
<Style Selector="^[IsOpen=True] /template/ Border#LayoutRoot">
<Setter Property="Background" Value="{DynamicResource AcrylicInAppFillColorDefaultBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource CardStrokeColorDefaultSolidBrush}" />
</Style>
</ControlTheme>
</ResourceDictionary>

4
src/Avalonia.Themes.Fluent2/Controls/ContentPage.xaml

@ -9,8 +9,8 @@
</Design.PreviewWith>
<ControlTheme x:Key="{x:Type ContentPage}" TargetType="ContentPage">
<Setter Property="Background" Value="{DynamicResource SystemControlPageBackgroundAltHighBrush}" />
<Setter Property="Foreground" Value="{DynamicResource SystemControlForegroundBaseHighBrush}" />
<Setter Property="Background" Value="{DynamicResource SolidBackgroundFillColorBaseBrush}" />
<Setter Property="Foreground" Value="{DynamicResource TextFillColorPrimaryBrush}" />
<Setter Property="Template">
<ControlTemplate>
<DockPanel>

14
src/Avalonia.Themes.Fluent2/Controls/DrawerPage.xaml

@ -13,11 +13,13 @@
<StreamGeometry x:Key="DrawerPaneButtonIcon">M3 17h18a1 1 0 0 1 .117 1.993L21 19H3a1 1 0 0 1-.117-1.993L3 17h18H3Zm0-6 18-.002a1 1 0 0 1 .117 1.993l-.117.007L3 13a1 1 0 0 1-.117-1.993L3 11l18-.002L3 11Zm0-6h18a1 1 0 0 1 .117 1.993L21 7H3a1 1 0 0 1-.117-1.993L3 5h18H3Z</StreamGeometry>
<x:Double x:Key="NavigationControlNavBarHeight">48</x:Double>
<SolidColorBrush x:Key="NavigationControlNavBarBackground" Color="{DynamicResource SystemChromeMediumColor}" />
<SolidColorBrush x:Key="NavigationControlNavBarBackground" Color="{DynamicResource SolidBackgroundFillColorBaseAlt}" />
<ControlTheme x:Key="{x:Type DrawerPage}" TargetType="DrawerPage">
<Setter Property="Background" Value="{DynamicResource SystemControlPageBackgroundAltHighBrush}" />
<Setter Property="Foreground" Value="{DynamicResource SystemControlForegroundBaseHighBrush}" />
<Setter Property="Background" Value="{DynamicResource SolidBackgroundFillColorBaseBrush}" />
<Setter Property="Foreground" Value="{DynamicResource TextFillColorPrimaryBrush}" />
<!-- Smoke layer shown behind the drawer in the overlay display modes. -->
<Setter Property="BackdropBrush" Value="{DynamicResource SmokeFillColorDefaultBrush}" />
<Setter Property="Template">
<ControlTemplate>
<SplitView Name="PART_SplitView"
@ -81,6 +83,9 @@
Padding="5"
Height="{DynamicResource NavigationControlNavBarHeight}"
Background="{DynamicResource NavigationControlNavBarBackground}"
BackgroundSizing="InnerBorderEdge"
BorderBrush="{DynamicResource DividerStrokeColorDefaultBrush}"
BorderThickness="0,0,0,1"
DockPanel.Dock="Top">
<DockPanel HorizontalAlignment="Stretch">
<DockPanel.Styles>
@ -128,6 +133,9 @@
Padding="5"
Height="{DynamicResource NavigationControlNavBarHeight}"
Background="{DynamicResource NavigationControlNavBarBackground}"
BackgroundSizing="InnerBorderEdge"
BorderBrush="{DynamicResource DividerStrokeColorDefaultBrush}"
BorderThickness="0,1,0,0"
DockPanel.Dock="Bottom"
IsVisible="False">
<DockPanel HorizontalAlignment="Stretch">

2
src/Avalonia.Themes.Fluent2/Controls/EmbeddableControlRoot.xaml

@ -3,7 +3,7 @@
x:ClassModifier="internal">
<ControlTheme x:Key="{x:Type EmbeddableControlRoot}" TargetType="EmbeddableControlRoot">
<Setter Property="Foreground" Value="{DynamicResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="Background" Value="{DynamicResource SystemRegionBrush}"/>
<Setter Property="Background" Value="{DynamicResource SolidBackgroundFillColorBaseBrush}"/>
<Setter Property="TopLevel.SystemBarColor" Value="{DynamicResource SystemControlBackgroundAltHighBrush}"/>
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}"/>
<Setter Property="FontFamily" Value="{DynamicResource ContentControlThemeFontFamily}" />

28
src/Avalonia.Themes.Fluent2/Controls/GridSplitter.xaml

@ -1,14 +1,28 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:ClassModifier="internal">
<Design.PreviewWith>
<Border Padding="20">
<Grid Width="200" Height="80" ColumnDefinitions="*,Auto,*">
<Border Grid.Column="0" Background="{DynamicResource CardBackgroundFillColorDefaultBrush}" />
<GridSplitter Grid.Column="1" />
<Border Grid.Column="2" Background="{DynamicResource CardBackgroundFillColorDefaultBrush}" />
</Grid>
</Border>
</Design.PreviewWith>
<!-- No WinUI counterpart (closest is the Windows Community Toolkit GridSplitter/SizerBase).
Harmonized with the Fluent 2 interaction fills: transparent at rest,
SubtleFillColorSecondary while hovered or dragged, accent drag preview. -->
<ControlTheme x:Key="{x:Type GridSplitter}" TargetType="GridSplitter">
<Setter Property="Focusable" Value="True" />
<Setter Property="MinWidth" Value="6" />
<Setter Property="MinHeight" Value="6" />
<Setter Property="Background" Value="{DynamicResource SystemAltMediumLowColor}" />
<!-- Transparent (not null) so the splitter stays hit-testable at rest. -->
<Setter Property="Background" Value="Transparent" />
<Setter Property="PreviewContent">
<Template>
<Rectangle Fill="{DynamicResource SystemAccentColor}" />
<Rectangle Fill="{DynamicResource AccentFillColorDefaultBrush}" />
</Template>
</Setter>
<Setter Property="Template">
@ -19,5 +33,13 @@
Background="{TemplateBinding Background}" />
</ControlTemplate>
</Setter>
<Style Selector="^:pointerover">
<Setter Property="Background" Value="{DynamicResource SubtleFillColorSecondaryBrush}" />
</Style>
<Style Selector="^:pressed">
<Setter Property="Background" Value="{DynamicResource SubtleFillColorSecondaryBrush}" />
</Style>
</ControlTheme>
</ResourceDictionary>

81
src/Avalonia.Themes.Fluent2/Controls/GroupBox.xaml

@ -3,77 +3,58 @@
xmlns:converters="clr-namespace:Avalonia.Controls.Converters;assembly=Avalonia.Controls"
x:ClassModifier="internal">
<Design.PreviewWith>
<GroupBox Padding="10" Margin="10">
<GroupBox Header="Header" Padding="10" Margin="10">
<TextBlock Text="Hello World" />
</GroupBox>
</Design.PreviewWith>
<!-- Kept for compatibility: the WPF-style gap-border template used this converter.
The Fluent 2 card template below no longer masks the border. -->
<converters:BorderGapMaskConverter x:Key="BorderGapMaskConverter" />
<!-- No WinUI counterpart (GroupBox is WPF-style). Harmonized with the WinUI card idiom:
a 1px CardStrokeColorDefault stroke with 4px corner radius over
CardBackgroundFillColorDefault, and the header rendered above the card as
BodyStrong text (14px SemiBold, TextFillColorPrimary). -->
<ControlTheme x:Key="{x:Type GroupBox}"
TargetType="GroupBox">
<Setter Property="BorderThickness" Value="{DynamicResource GroupBoxBorderThickness}" />
<Setter Property="Background" Value="{DynamicResource GroupBoxBackground}" />
<Setter Property="BorderBrush" Value="{DynamicResource GroupBoxBorderBrush}" />
<Setter Property="Background" Value="{DynamicResource CardBackgroundFillColorDefaultBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource CardStrokeColorDefaultBrush}" />
<Setter Property="Padding" Value="{DynamicResource GroupBoxPadding}" />
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="Template">
<ControlTemplate>
<Grid x:Name="RootGrid" UseLayoutRounding="true" ColumnDefinitions="6,Auto,*,6" RowDefinitions="Auto,Auto,*,6">
<!-- Separate Border for the background because if the background is set in the Border with the Header the opacity mask will be applied to the background as well. -->
<Border Grid.Row="1"
Grid.RowSpan="3"
Grid.Column="0"
Grid.ColumnSpan="4"
CornerRadius="{TemplateBinding CornerRadius}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="Transparent"
Background="{TemplateBinding Background}"/>
<Border Grid.Row="1"
Grid.RowSpan="3"
Grid.ColumnSpan="4"
CornerRadius="{TemplateBinding CornerRadius}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}">
<Border.OpacityMask>
<MultiBinding Converter="{StaticResource BorderGapMaskConverter}"
ConverterParameter="6">
<Binding ElementName="Header"
Path="Bounds.Width"/>
<Binding RelativeSource="{RelativeSource Self}"
Path="Bounds.Width"/>
<Binding RelativeSource="{RelativeSource Self}"
Path="Bounds.Height"/>
</MultiBinding>
</Border.OpacityMask>
</Border>
<!-- ContentPresenter for the header -->
<Grid x:Name="RootGrid" UseLayoutRounding="true" RowDefinitions="Auto,*">
<!-- Header above the card content area -->
<Border x:Name="Header"
Padding="3,0,3,0"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1">
Padding="0,0,0,8">
<ContentPresenter Name="PART_HeaderPresenter"
Content="{TemplateBinding Header}"
FontSize="{DynamicResource GroupBoxHeaderFontSize}"
Foreground="{DynamicResource GroupBoxHeaderForeground}"
FontSize="{DynamicResource ControlContentThemeFontSize}"
FontWeight="SemiBold"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
UseLayoutRounding="{TemplateBinding UseLayoutRounding}" />
</Border>
<!-- Primary content for GroupBox -->
<ContentPresenter Grid.Row="2"
Grid.Column="1"
Grid.ColumnSpan="2"
Name="PART_ContentPresenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
UseLayoutRounding="{TemplateBinding UseLayoutRounding}"
Margin="{TemplateBinding Padding}" />
<!-- Card surface with the primary content -->
<Border Grid.Row="1"
CornerRadius="{TemplateBinding CornerRadius}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
BackgroundSizing="InnerBorderEdge">
<ContentPresenter Name="PART_ContentPresenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
UseLayoutRounding="{TemplateBinding UseLayoutRounding}"
Margin="{TemplateBinding Padding}" />
</Border>
</Grid>
</ControlTemplate>
</Setter>

16
src/Avalonia.Themes.Fluent2/Controls/HeaderedContentControl.xaml

@ -1,6 +1,16 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:ClassModifier="internal">
<Design.PreviewWith>
<Border Padding="20">
<HeaderedContentControl Header="Header">
<TextBlock Text="Content" />
</HeaderedContentControl>
</Border>
</Design.PreviewWith>
<!-- No WinUI counterpart. The header follows the WinUI BodyStrong text style
(14px SemiBold, TextFillColorPrimary) with an 8px gap between header and content. -->
<ControlTheme x:Key="{x:Type HeaderedContentControl}"
TargetType="HeaderedContentControl">
@ -16,6 +26,10 @@
<ContentPresenter Name="PART_HeaderPresenter"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
FontSize="{DynamicResource ControlContentThemeFontSize}"
FontWeight="SemiBold"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
Margin="0,0,0,8"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Grid.Row="0" />
@ -36,7 +50,7 @@
<Style Selector="^ /template/ ContentPresenter#PART_HeaderPresenter">
<Setter Property="RecognizesAccessKey" Value="True" />
</Style>
</Style>
</ControlTheme>
</ResourceDictionary>

15
src/Avalonia.Themes.Fluent2/Controls/Label.xaml

@ -1,8 +1,19 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:ClassModifier="internal">
<Design.PreviewWith>
<Border Padding="20">
<StackPanel Spacing="8">
<Label Content="_Label" />
<Label Content="Disabled label" IsEnabled="False" />
</StackPanel>
</Border>
</Design.PreviewWith>
<!-- No WinUI counterpart (Label is WPF-style). Harmonized with the Fluent 2 text tokens:
TextFillColorPrimary at rest, TextFillColorDisabled when disabled. -->
<ControlTheme x:Key="{x:Type Label}" TargetType="Label">
<Setter Property="Foreground" Value="{DynamicResource TextFillColorPrimaryBrush}" />
<Setter Property="Padding" Value="3"/>
<Setter Property="Template">
<ControlTemplate>
@ -22,5 +33,9 @@
<Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="RecognizesAccessKey" Value="True" />
</Style>
<Style Selector="^:disabled">
<Setter Property="Foreground" Value="{DynamicResource TextFillColorDisabledBrush}" />
</Style>
</ControlTheme>
</ResourceDictionary>

29
src/Avalonia.Themes.Fluent2/Controls/ManagedFileChooser.xaml

@ -134,7 +134,7 @@
</internal:ResourceSelectorConverter>
</ResourceDictionary>
</ControlTheme.Resources>
<Setter Property="Background" Value="{DynamicResource SystemRegionBrush}"/>
<Setter Property="Background" Value="{DynamicResource SolidBackgroundFillColorBaseBrush}"/>
<Setter Property="Template"
x:DataType="internal:ManagedFileChooserViewModel">
<ControlTemplate>
@ -160,7 +160,7 @@
</ListBox.ItemTemplate>
</ListBox>
<DockPanel x:Name="NavBar" DockPanel.Dock="Top" Margin="8,5,8,0" VerticalAlignment="Center">
<Rectangle Fill="{DynamicResource SystemControlHighlightAltBaseMediumLowBrush}" Height="1" Margin="0,5,0,0" DockPanel.Dock="Bottom"/>
<Rectangle Fill="{DynamicResource DividerStrokeColorDefaultBrush}" Height="1" Margin="0,5,0,0" DockPanel.Dock="Bottom"/>
<DockPanel Margin="4,0">
<Button Command="{Binding GoUp}" DockPanel.Dock="Left" Margin="0,0,8,0">
<Path Data="M 0 7 L 7 0 L 14 7 M 7 0 L 7 16" Stroke="{CompiledBinding $parent[Button].Foreground}" StrokeThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,1,0,-1"/>
@ -177,7 +177,7 @@
</DockPanel>
</DockPanel>
<DockPanel Margin="8,0,8,5" DockPanel.Dock="Bottom">
<Rectangle Fill="{DynamicResource SystemControlHighlightAltBaseMediumLowBrush}" Height="1" Margin="0,0,0,5" DockPanel.Dock="Top"/>
<Rectangle Fill="{DynamicResource DividerStrokeColorDefaultBrush}" Height="1" Margin="0,0,0,5" DockPanel.Dock="Top"/>
<DockPanel Margin="4,0">
<DockPanel DockPanel.Dock="Top" Margin="0,0,0,4">
<ComboBox DockPanel.Dock="Right"
@ -209,7 +209,7 @@
</Grid.ColumnDefinitions>
<Grid.Styles>
<Style Selector="GridSplitter">
<Setter Property="Background" Value="{DynamicResource SystemControlHighlightAltBaseMediumLowBrush}"/>
<Setter Property="Background" Value="{DynamicResource DividerStrokeColorDefaultBrush}"/>
<Setter Property="Template">
<ControlTemplate>
<Border VerticalAlignment="Stretch" BorderThickness="0" Background="#01000000">
@ -219,13 +219,13 @@
</Setter>
</Style>
</Grid.Styles>
<TextBlock Grid.Column="1" Text="{DynamicResource StringManagedFileChooserNameColumn}" />
<TextBlock Grid.Column="1" Foreground="{DynamicResource TextFillColorSecondaryBrush}" Text="{DynamicResource StringManagedFileChooserNameColumn}" />
<GridSplitter Grid.Column="2" />
<TextBlock Grid.Column="3" Text="{DynamicResource StringManagedFileChooserDateModifiedColumn}" />
<TextBlock Grid.Column="3" Foreground="{DynamicResource TextFillColorSecondaryBrush}" Text="{DynamicResource StringManagedFileChooserDateModifiedColumn}" />
<GridSplitter Grid.Column="4" />
<TextBlock Grid.Column="5" Text="{DynamicResource StringManagedFileChooserTypeColumn}" />
<TextBlock Grid.Column="5" Foreground="{DynamicResource TextFillColorSecondaryBrush}" Text="{DynamicResource StringManagedFileChooserTypeColumn}" />
<GridSplitter Grid.Column="6" />
<TextBlock Grid.Column="7" Text="{DynamicResource StringManagedFileChooserSizeColumn}" />
<TextBlock Grid.Column="7" Foreground="{DynamicResource TextFillColorSecondaryBrush}" Text="{DynamicResource StringManagedFileChooserSizeColumn}" />
<GridSplitter Grid.Column="8" />
</Grid>
<ListBox x:Name="PART_Files"
@ -277,13 +277,14 @@
</Setter>
<Style Selector="^ /template/ ListBox#QuickLinks">
<Setter Property="Margin" Value="0"/>
<Setter Property="Background" Value="{DynamicResource SystemControlBackgroundChromeMediumBrush}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Background" Value="{DynamicResource LayerFillColorDefaultBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource DividerStrokeColorDefaultBrush}"/>
<Setter Property="BorderThickness" Value="0,0,1,0"/>
<Setter Property="Width" Value="240"/>
<Setter Property="Padding" Value="0,20"/>
<Setter Property="Template">
<ControlTemplate>
<Border Name="border" BoxShadow="inset -6 0 3 -3 #20000000" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<Border Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer Name="PART_ScrollViewer" HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}" VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}">
<ItemsPresenter Name="PART_ItemsPresenter"
ItemsPanel="{TemplateBinding ItemsPanel}"
@ -300,7 +301,7 @@
<ControlTemplate>
<Border x:Name="LayoutRoot" CornerRadius="2" Margin="10,0">
<Panel>
<Border x:Name="SelectedLine" HorizontalAlignment="Left" Margin="2,6" CornerRadius="0.5" Width="3" Background="{DynamicResource SystemControlHighlightAccentBrush}" IsVisible="{TemplateBinding IsSelected}"/>
<Border x:Name="SelectedLine" HorizontalAlignment="Left" Margin="2,6" CornerRadius="0.5" Width="3" Background="{DynamicResource AccentFillColorDefaultBrush}" IsVisible="{TemplateBinding IsSelected}"/>
<ContentPresenter Name="PART_ContentPresenter"
Background="Transparent"
BorderBrush="Transparent"
@ -317,10 +318,10 @@
</Setter>
<Style Selector="^:pointerover /template/ Border#LayoutRoot">
<Setter Property="Background" Value="{DynamicResource SystemControlBackgroundAltMediumBrush}"/>
<Setter Property="Background" Value="{DynamicResource SubtleFillColorSecondaryBrush}"/>
</Style>
<Style Selector="^:selected /template/ Border#LayoutRoot">
<Setter Property="Background" Value="{DynamicResource SystemControlBackgroundAltMediumHighBrush}"/>
<Setter Property="Background" Value="{DynamicResource SubtleFillColorTertiaryBrush}"/>
</Style>
</ControlTheme>
</Setter>

27
src/Avalonia.Themes.Fluent2/Controls/NavigationPage.xaml

@ -10,8 +10,8 @@
<StreamGeometry x:Key="NavigationPageBackIcon">M12.7347,4.20949 C13.0332,3.92233 13.508,3.93153 13.7952,4.23005 C14.0823,4.52857 14.0731,5.00335 13.7746,5.29051 L5.50039,13.25 L24.2532,13.25 C24.6674,13.25 25.0032,13.5858 25.0032,13.9999982 C25.0032,14.4142 24.6674,14.75 24.2532,14.75 L5.50137,14.75 L13.7746,22.7085 C14.0731,22.9957 14.0823,23.4705 13.7952,23.769 C13.508,24.0675 13.0332,24.0767 12.7347,23.7896 L3.30673,14.7202 C2.89776,14.3268 2.89776,13.6723 3.30673,13.2788 L12.7347,4.20949 Z</StreamGeometry>
<SolidColorBrush x:Key="NavigationBarBackground" Color="{DynamicResource SystemChromeMediumColor}" />
<SolidColorBrush x:Key="NavigationBarForeground" Color="{DynamicResource SystemBaseMediumColor}" />
<SolidColorBrush x:Key="NavigationBarBackground" Color="{DynamicResource SolidBackgroundFillColorBaseAlt}" />
<SolidColorBrush x:Key="NavigationBarForeground" Color="{DynamicResource TextFillColorPrimary}" />
<ControlTheme x:Key="{x:Type NavigationPage}" TargetType="NavigationPage">
<!-- Transparent keeps the hit-test surface active for the back-swipe gesture edge area. -->
@ -75,6 +75,9 @@
ZIndex="1"
VerticalAlignment="Top"
ClipToBounds="True"
BackgroundSizing="InnerBorderEdge"
BorderBrush="{DynamicResource DividerStrokeColorDefaultBrush}"
BorderThickness="0,0,0,1"
Height="{TemplateBinding EffectiveBarHeight}">
<Grid Margin="12,0,0,0" ColumnDefinitions="Auto, *, Auto">
<Grid.Styles>
@ -83,16 +86,16 @@
<Setter Property="CornerRadius" Value="4" />
</Style>
<Style Selector="Button#PART_BackButton:pointerover /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="{DynamicResource SystemControlHighlightListLowBrush}" />
<Setter Property="Background" Value="{DynamicResource SubtleFillColorSecondaryBrush}" />
</Style>
<Style Selector="Button#PART_BackButton:pressed /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="{DynamicResource SystemControlHighlightListMediumBrush}" />
<Setter Property="Background" Value="{DynamicResource SubtleFillColorTertiaryBrush}" />
</Style>
<Style Selector="Button#PART_BackButton:disabled">
<Setter Property="Opacity" Value="0.4" />
</Style>
<Style Selector="Button#PART_BackButton:focus-visible /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="BorderBrush" Value="{DynamicResource SystemControlForegroundBaseHighBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource FocusStrokeColorOuterBrush}" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="CornerRadius" Value="4" />
</Style>
@ -104,20 +107,23 @@
<Setter Property="CornerRadius" Value="0" />
</Style>
<Style Selector="Button#PART_OverflowButton:pointerover /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="{DynamicResource SystemControlHighlightListLowBrush}" />
<Setter Property="Background" Value="{DynamicResource SubtleFillColorSecondaryBrush}" />
</Style>
<Style Selector="Button#PART_OverflowButton:pressed /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="{DynamicResource SystemControlHighlightListMediumBrush}" />
<Setter Property="Background" Value="{DynamicResource SubtleFillColorTertiaryBrush}" />
</Style>
</Grid.Styles>
<Button x:Name="PART_BackButton"
Grid.Column="0"
Background="Transparent"
BorderThickness="0"
Foreground="{DynamicResource NavigationBarForeground}"
IsVisible="{TemplateBinding IsBackButtonEffectivelyVisible}"
VerticalAlignment="Stretch"
Padding="8,0"
Width="40"
Height="40"
VerticalAlignment="Center"
Padding="0"
ToolTip.Tip="{x:Null}">
<Panel Background="Transparent">
<Path Data="{DynamicResource NavigationPageBackIcon}"
@ -137,7 +143,8 @@
<ContentPresenter Name="PART_Header"
Grid.Column="1"
FontSize="20"
FontSize="14"
FontWeight="SemiBold"
Foreground="{DynamicResource NavigationBarForeground}"
Content="{Binding CurrentPage?.Header, RelativeSource={RelativeSource TemplatedParent}, FallbackValue={x:Null}}"
ContentTemplate="{Binding CurrentPage?.HeaderTemplate, RelativeSource={RelativeSource TemplatedParent}, FallbackValue={x:Null}}"

159
src/Avalonia.Themes.Fluent2/Controls/NotificationCard.xaml

@ -2,30 +2,134 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:ClassModifier="internal">
<Design.PreviewWith>
<Border Padding="0" Background="White">
<NotificationCard Content="Testing" />
<Border Padding="16">
<StackPanel Spacing="8">
<NotificationCard Content="Testing" />
<NotificationCard Content="Testing" NotificationType="Success" />
<NotificationCard Content="Testing" NotificationType="Warning" />
<NotificationCard Content="Testing" NotificationType="Error" />
</StackPanel>
</Border>
</Design.PreviewWith>
<!-- WinUI reference: InfoBar.xaml + InfoBar_themeresources.xaml, winui3/release/1.4.2 (via Uno.UI.FluentTheme.v2).
InfoBar idiom: 48px min-height card, ControlCornerRadius, 1px CardStrokeColorDefault border
(BackgroundSizing InnerBorderEdge), severity tint background (SystemFillColor*BackgroundBrush) drawn
over a SolidBackgroundFillColorBase underlay (the attention tint is translucent by design), a 16px
severity badge icon (SystemFillColor*Brush) and a 32px subtle-fill close button with a 10px dismiss
glyph. Metrics per InfoBar_themeresources: ContentRootPadding 16,0,0,0; IconMargin 0,16,14,16;
PanelMargin 0,0,16,0. The v1 severity pseudo-class mechanism (:information/:success/:warning/:error)
is kept and retargeted from the old 4px header bar to the card background + badge icon.
The v1 NotificationCard* brush aliases live in Accents/FluentControlResources.xaml (shared file) and
still carry v1 values; this template consumes the Fluent 2 tokens directly (see conversion notes). -->
<!-- Severity badge icons: 16x16 filled circle with the glyph cut out (even-odd fill),
approximating the Segoe Fluent InfoBar badge glyphs (F13F/F13E/F13C/F13D over F136). -->
<StreamGeometry x:Key="NotificationCardInformationIconGeometry">M8,0 A8,8 0 1 0 8,16 A8,8 0 1 0 8,0 Z M8,3.25 A1.25,1.25 0 1 0 8,5.75 A1.25,1.25 0 1 0 8,3.25 Z M7,7 L9,7 L9,12.75 L7,12.75 Z</StreamGeometry>
<StreamGeometry x:Key="NotificationCardSuccessIconGeometry">M8,0 A8,8 0 1 0 8,16 A8,8 0 1 0 8,0 Z M4.5,8.45 L7.05,11 L11.5,6.55 L10.44,5.49 L7.05,8.88 L5.56,7.39 Z</StreamGeometry>
<StreamGeometry x:Key="NotificationCardWarningIconGeometry">M8,0 A8,8 0 1 0 8,16 A8,8 0 1 0 8,0 Z M7,3.75 L9,3.75 L9,9.5 L7,9.5 Z M8,10.75 A1.25,1.25 0 1 0 8,13.25 A1.25,1.25 0 1 0 8,10.75 Z</StreamGeometry>
<StreamGeometry x:Key="NotificationCardErrorIconGeometry">M8,0 A8,8 0 1 0 8,16 A8,8 0 1 0 8,0 Z M4.22,5.28 L6.94,8 L4.22,10.72 L5.28,11.78 L8,9.06 L10.72,11.78 L11.78,10.72 L9.06,8 L11.78,5.28 L10.72,4.22 L8,6.94 L5.28,4.22 Z</StreamGeometry>
<StreamGeometry x:Key="NotificationCardDismissIconGeometry">M0.75,0.75 L9.25,9.25 M9.25,0.75 L0.75,9.25</StreamGeometry>
<!-- InfoBar close button: subtle-fill 32px square, ControlCornerRadius, 83ms fill cross-fade. -->
<ControlTheme x:Key="Fluent2NotificationCardCloseButtonTheme" TargetType="Button">
<Setter Property="Background" Value="{DynamicResource SubtleFillColorTransparentBrush}" />
<Setter Property="BackgroundSizing" Value="InnerBorderEdge" />
<Setter Property="BorderBrush" Value="{DynamicResource ControlFillColorTransparentBrush}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="Padding" Value="0" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<ControlTemplate>
<ContentPresenter x:Name="PART_ContentPresenter"
Background="{TemplateBinding Background}"
BackgroundSizing="{TemplateBinding BackgroundSizing}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Padding="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
<ContentPresenter.Transitions>
<Transitions>
<BrushTransition Property="Background" Duration="0:0:0.083" />
</Transitions>
</ContentPresenter.Transitions>
</ContentPresenter>
</ControlTemplate>
</Setter>
<Style Selector="^:pointerover /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="{DynamicResource SubtleFillColorSecondaryBrush}" />
</Style>
<Style Selector="^:pressed /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="{DynamicResource SubtleFillColorTertiaryBrush}" />
</Style>
</ControlTheme>
<ControlTheme x:Key="{x:Type NotificationCard}" TargetType="NotificationCard">
<Setter Property="UseLayoutRounding" Value="True"/>
<Setter Property="Width" Value="350"/>
<Setter Property="Foreground" Value="{DynamicResource NotificationCardForegroundBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource TextFillColorPrimaryBrush}"/>
<Setter Property="RenderTransformOrigin" Value="50%,75%"/>
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="{DynamicResource NotificationCardBackgroundBrush}" />
<!-- InfoBarBorderThickness=1, InfoBarBorderBrush=CardStrokeColorDefaultBrush -->
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="{DynamicResource CardStrokeColorDefaultBrush}" />
<!-- Like WinUI, Background is transparent by default and overrides the severity tint when set. -->
<Setter Property="Background" Value="Transparent" />
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="Template">
<ControlTemplate>
<LayoutTransformControl Name="PART_LayoutTransformControl" UseRenderTransform="True">
<Border CornerRadius="{TemplateBinding CornerRadius}" BoxShadow="0 6 8 0 #4F000000" Margin="5 5 5 10">
<Border Background="{TemplateBinding Background}"
<!-- Solid underlay: the attention severity tint is translucent and is designed to sit on the
solid app background (mica fallback). A soft ambient shadow is kept from v1 because these
cards float above app content, unlike an inline WinUI InfoBar. -->
<Border Background="{DynamicResource SolidBackgroundFillColorBaseBrush}"
CornerRadius="{TemplateBinding CornerRadius}"
BoxShadow="0 4 8 0 #26000000">
<Border x:Name="CardBorder"
Background="{DynamicResource SystemFillColorAttentionBackgroundBrush}"
BackgroundSizing="InnerBorderEdge"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
ClipToBounds="True">
<DockPanel>
<Panel x:Name="PART_HeaderBar" Height="4" Background="{DynamicResource NotificationCardProgressBackgroundBrush}" DockPanel.Dock="Top" />
<ContentPresenter Name="PART_ContentPresenter" MinHeight="64" Content="{TemplateBinding Content}" />
<!-- v1 severity header bar, retired by the InfoBar look but kept for compatibility. -->
<Panel x:Name="PART_HeaderBar" Height="4" IsVisible="False" Background="{DynamicResource NotificationCardProgressBackgroundBrush}" DockPanel.Dock="Top" />
<Border Background="{TemplateBinding Background}" CornerRadius="{TemplateBinding CornerRadius}">
<Grid ColumnDefinitions="Auto,*,Auto" MinHeight="48" Margin="16,0,0,0">
<Path x:Name="SeverityIcon"
Grid.Column="0"
Width="16" Height="16"
Margin="0,16,14,16"
VerticalAlignment="Top"
Stretch="Uniform"
Data="{StaticResource NotificationCardInformationIconGeometry}"
Fill="{DynamicResource SystemFillColorAttentionBrush}" />
<ContentPresenter Name="PART_ContentPresenter"
Grid.Column="1"
Margin="0,0,16,0"
Content="{TemplateBinding Content}" />
<Button x:Name="CloseButton"
Grid.Column="2"
Theme="{StaticResource Fluent2NotificationCardCloseButtonTheme}"
NotificationCard.CloseOnClick="True"
Width="32" Height="32"
Margin="8"
VerticalAlignment="Top">
<Path Width="10" Height="10"
Stretch="Uniform"
Data="{StaticResource NotificationCardDismissIconGeometry}"
Stroke="{DynamicResource TextFillColorPrimaryBrush}"
StrokeThickness="1" />
</Button>
</Grid>
</Border>
</DockPanel>
</Border>
</Border>
@ -83,17 +187,38 @@
</Style.Animations>
</Style>
<Style Selector="^:information /template/ Panel#PART_HeaderBar">
<Setter Property="Background" Value="{DynamicResource NotificationCardInformationBackgroundBrush}"/>
<!-- Severity states, per InfoBar_themeresources:
background = SystemFillColor*BackgroundBrush, badge icon = SystemFillColor*Brush. -->
<Style Selector="^:information /template/ Border#CardBorder">
<Setter Property="Background" Value="{DynamicResource SystemFillColorAttentionBackgroundBrush}"/>
</Style>
<Style Selector="^:information /template/ Path#SeverityIcon">
<Setter Property="Data" Value="{StaticResource NotificationCardInformationIconGeometry}"/>
<Setter Property="Fill" Value="{DynamicResource SystemFillColorAttentionBrush}"/>
</Style>
<Style Selector="^:success /template/ Panel#PART_HeaderBar">
<Setter Property="Background" Value="{DynamicResource NotificationCardSuccessBackgroundBrush}"/>
<Style Selector="^:success /template/ Border#CardBorder">
<Setter Property="Background" Value="{DynamicResource SystemFillColorSuccessBackgroundBrush}"/>
</Style>
<Style Selector="^:warning /template/ Panel#PART_HeaderBar">
<Setter Property="Background" Value="{DynamicResource NotificationCardWarningBackgroundBrush}"/>
<Style Selector="^:success /template/ Path#SeverityIcon">
<Setter Property="Data" Value="{StaticResource NotificationCardSuccessIconGeometry}"/>
<Setter Property="Fill" Value="{DynamicResource SystemFillColorSuccessBrush}"/>
</Style>
<Style Selector="^:warning /template/ Border#CardBorder">
<Setter Property="Background" Value="{DynamicResource SystemFillColorCautionBackgroundBrush}"/>
</Style>
<Style Selector="^:warning /template/ Path#SeverityIcon">
<Setter Property="Data" Value="{StaticResource NotificationCardWarningIconGeometry}"/>
<Setter Property="Fill" Value="{DynamicResource SystemFillColorCautionBrush}"/>
</Style>
<Style Selector="^:error /template/ Border#CardBorder">
<Setter Property="Background" Value="{DynamicResource SystemFillColorCriticalBackgroundBrush}"/>
</Style>
<Style Selector="^:error /template/ Panel#PART_HeaderBar">
<Setter Property="Background" Value="{DynamicResource NotificationCardErrorBackgroundBrush}"/>
<Style Selector="^:error /template/ Path#SeverityIcon">
<Setter Property="Data" Value="{StaticResource NotificationCardErrorIconGeometry}"/>
<Setter Property="Fill" Value="{DynamicResource SystemFillColorCriticalBrush}"/>
</Style>
</ControlTheme>
</ResourceDictionary>

8
src/Avalonia.Themes.Fluent2/Controls/RefreshContainer.xaml

@ -1,8 +1,16 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:ClassModifier="internal">
<!-- WinUI reference: RefreshContainer.xaml / RefreshContainer_themeresources.xaml
(DefaultRefreshContainerStyle). Structure matches WinUI: a root Grid hosting the
content presenter with the visualizer presenter Grid layered on top. WinUI's
RefreshContainerBackgroundBrush is Transparent in every theme. WinUI's Foreground
setter (RefreshContainerForegroundBrush) is intentionally not mirrored so user
content keeps its inherited foreground; the visualizer brings its own. -->
<ControlTheme x:Key="{x:Type RefreshContainer}"
TargetType="RefreshContainer">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<ControlTemplate>
<Grid>

7
src/Avalonia.Themes.Fluent2/Controls/RefreshVisualizer.xaml

@ -1,6 +1,11 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:ClassModifier="internal">
<!-- WinUI reference: RefreshVisualizer.xaml / RefreshVisualizer_themeresources.xaml.
Structure matches WinUI (root Grid, MinHeight 80, Height 100, transparent
background). The progress glyph inherits the control Foreground, harmonized to
AccentFillColorDefault so the refresh affordance reads as the accent-colored
progress indicator. -->
<ControlTheme x:Key="{x:Type RefreshVisualizer}"
TargetType="RefreshVisualizer">
<Setter Property="IsTabStop" Value="False"/>
@ -10,7 +15,7 @@
<Setter Property="Background"
Value="{DynamicResource RefreshVisualizerBackground}"/>
<Setter Property="Foreground"
Value="{DynamicResource RefreshVisualizerForeground}"/>
Value="{DynamicResource AccentFillColorDefaultBrush}"/>
<Setter Property="Content">
<Template>
<PathIcon Name="PART_Icon"

45
src/Avalonia.Themes.Fluent2/Controls/TabbedPage.xaml

@ -19,20 +19,20 @@
<!-- Backgrounds -->
<SolidColorBrush x:Key="TabbedPageTabItemHeaderBackgroundUnselected" Color="Transparent" />
<SolidColorBrush x:Key="TabbedPageTabItemHeaderBackgroundSelected" Color="Transparent" />
<SolidColorBrush x:Key="TabbedPageTabItemHeaderBackgroundUnselectedPointerOver" Color="{DynamicResource SystemListLowColor}" />
<SolidColorBrush x:Key="TabbedPageTabItemHeaderBackgroundUnselectedPointerOver" Color="{DynamicResource SubtleFillColorSecondary}" />
<SolidColorBrush x:Key="TabbedPageTabItemHeaderBackgroundSelectedPointerOver" Color="Transparent" />
<SolidColorBrush x:Key="TabbedPageTabItemHeaderBackgroundUnselectedPressed" Color="{DynamicResource SystemListMediumColor}" />
<SolidColorBrush x:Key="TabbedPageTabItemHeaderBackgroundUnselectedPressed" Color="{DynamicResource SubtleFillColorTertiary}" />
<SolidColorBrush x:Key="TabbedPageTabItemHeaderBackgroundSelectedPressed" Color="Transparent" />
<SolidColorBrush x:Key="TabbedPageTabItemHeaderBackgroundDisabled" Color="Transparent" />
<!-- Foregrounds (override via TabbedPageTabItemHeaderForegroundSelected / TabbedPageTabItemHeaderForegroundUnselected resources) -->
<SolidColorBrush x:Key="TabbedPageTabItemHeaderForegroundUnselected" Color="{DynamicResource SystemBaseMediumColor}" />
<SolidColorBrush x:Key="TabbedPageTabItemHeaderForegroundSelected" Color="{DynamicResource SystemAccentColor}" />
<SolidColorBrush x:Key="TabbedPageTabItemHeaderForegroundDisabled" Color="{DynamicResource SystemBaseLowColor}" />
<x:Double x:Key="TabbedPageTabItemHeaderPipeThickness">2</x:Double>
<SolidColorBrush x:Key="TabbedPageTabItemHeaderForegroundUnselected" Color="{DynamicResource TextFillColorSecondary}" />
<SolidColorBrush x:Key="TabbedPageTabItemHeaderForegroundSelected" Color="{DynamicResource TextFillColorPrimary}" />
<SolidColorBrush x:Key="TabbedPageTabItemHeaderForegroundDisabled" Color="{DynamicResource TextFillColorDisabled}" />
<x:Double x:Key="TabbedPageTabItemHeaderPipeThickness">3</x:Double>
<x:Double x:Key="TabbedPageTabItemHeaderVerticalPipeHeight">18</x:Double>
<CornerRadius x:Key="TabbedPageTabItemHeaderIndicatorCornerRadius">0</CornerRadius>
<CornerRadius x:Key="TabbedPageTabItemHeaderIndicatorCornerRadius">1.5</CornerRadius>
<Thickness x:Key="TabbedPageTabItemHeaderIndicatorMargin">0</Thickness>
<!-- Tab item sizing & shape -->
@ -46,11 +46,12 @@
<x:Double x:Key="TabbedPageTabItemHeaderFontSize">12</x:Double>
<x:Double x:Key="TabbedPageTabItemHeaderSpacing">4</x:Double>
<!-- Tab strip (bar) styling -->
<SolidColorBrush x:Key="TabbedPageTabStripBackground" Color="Transparent" />
<!-- Tab strip (bar) styling. Divider edge defaults to the top (Bottom placement);
the other placements are corrected via TabStripPlacement styles below. -->
<SolidColorBrush x:Key="TabbedPageTabStripBackground" Color="{DynamicResource SolidBackgroundFillColorBaseAlt}" />
<CornerRadius x:Key="TabbedPageTabStripCornerRadius">0</CornerRadius>
<Thickness x:Key="TabbedPageTabStripBorderThickness">0</Thickness>
<SolidColorBrush x:Key="TabbedPageTabStripBorderBrush" Color="Transparent" />
<Thickness x:Key="TabbedPageTabStripBorderThickness">0,1,0,0</Thickness>
<SolidColorBrush x:Key="TabbedPageTabStripBorderBrush" Color="{DynamicResource DividerStrokeColorDefault}" />
<Thickness x:Key="TabbedPageTabStripMargin">0</Thickness>
<Thickness x:Key="TabbedPageTabStripPadding">0</Thickness>
@ -66,6 +67,7 @@
<DockPanel>
<Border Name="PART_TabStrip"
Background="{TemplateBinding Background}"
BackgroundSizing="InnerBorderEdge"
CornerRadius="{TemplateBinding CornerRadius}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
@ -98,6 +100,17 @@
<Setter Property="Rows" Value="0" />
<Setter Property="Columns" Value="1" />
</Style>
<!-- Keep the 1px divider on the edge that faces the content for each placement. -->
<Style Selector="^[TabStripPlacement=Top]">
<Setter Property="BorderThickness" Value="0,0,0,1" />
</Style>
<Style Selector="^[TabStripPlacement=Left]">
<Setter Property="BorderThickness" Value="0,0,1,0" />
</Style>
<Style Selector="^[TabStripPlacement=Right]">
<Setter Property="BorderThickness" Value="1,0,0,0" />
</Style>
</ControlTheme>
<!-- TabbedPage TabItem theme -->
@ -114,7 +127,7 @@
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="IndicatorTemplate">
<DataTemplate>
<Border Background="{Binding $parent[TabItem].Foreground}"
<Border Background="{DynamicResource AccentFillColorDefaultBrush}"
CornerRadius="{DynamicResource TabbedPageTabItemHeaderIndicatorCornerRadius}"
Margin="{DynamicResource TabbedPageTabItemHeaderIndicatorMargin}"
HorizontalAlignment="Stretch"
@ -184,7 +197,7 @@
<Style Selector="^[TabStripPlacement=Right]">
<Setter Property="IndicatorTemplate">
<DataTemplate>
<Border Background="{Binding $parent[TabItem].Foreground}"
<Border Background="{DynamicResource AccentFillColorDefaultBrush}"
CornerRadius="{DynamicResource TabbedPageTabItemHeaderIndicatorCornerRadius}"
Margin="{DynamicResource TabbedPageTabItemHeaderIndicatorMargin}"
Width="{DynamicResource TabbedPageTabItemHeaderPipeThickness}"
@ -199,7 +212,7 @@
<Style Selector="^[TabStripPlacement=Left]">
<Setter Property="IndicatorTemplate">
<DataTemplate>
<Border Background="{Binding $parent[TabItem].Foreground}"
<Border Background="{DynamicResource AccentFillColorDefaultBrush}"
CornerRadius="{DynamicResource TabbedPageTabItemHeaderIndicatorCornerRadius}"
Margin="{DynamicResource TabbedPageTabItemHeaderIndicatorMargin}"
Width="{DynamicResource TabbedPageTabItemHeaderPipeThickness}"
@ -240,13 +253,13 @@
<!-- Focus visible -->
<Style Selector="^:focus-visible /template/ Border#PART_LayoutRoot">
<Setter Property="BorderBrush" Value="{DynamicResource SystemControlForegroundBaseHighBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource FocusStrokeColorOuterBrush}" />
<Setter Property="BorderThickness" Value="2" />
</Style>
</ControlTheme>
<ControlTheme x:Key="{x:Type TabbedPage}" TargetType="TabbedPage">
<Setter Property="Background" Value="{DynamicResource SystemControlPageBackgroundAltHighBrush}" />
<Setter Property="Background" Value="{DynamicResource SolidBackgroundFillColorBaseBrush}" />
<Setter Property="Template">
<ControlTemplate>
<Panel Background="{TemplateBinding Background}">

10
src/Avalonia.Themes.Fluent2/Controls/TextSelectionHandle.xaml

@ -17,10 +17,10 @@
<DrawingImage x:Key="TextSelectionHandleDrawing">
<DrawingImage.Drawing>
<GeometryDrawing Geometry="{DynamicResource TextSelectionHandlePath}"
Brush="{DynamicResource TextControlSelectionHighlightColor}"
Brush="{DynamicResource AccentFillColorDefaultBrush}"
>
<GeometryDrawing.Pen>
<Pen Thickness="0.5" Brush="{DynamicResource SystemControlForegroundBaseHighBrush}" LineJoin="Round"/>
<Pen Thickness="0.5" Brush="{DynamicResource ControlStrokeColorDefaultBrush}" LineJoin="Round"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingImage.Drawing>
@ -29,10 +29,10 @@
<DrawingImage x:Key="TextCaretHandleDrawing">
<DrawingImage.Drawing>
<GeometryDrawing Geometry="{DynamicResource TextCaretHandlePath}"
Brush="{DynamicResource TextControlSelectionHighlightColor}"
Brush="{DynamicResource AccentFillColorDefaultBrush}"
>
<GeometryDrawing.Pen>
<Pen Thickness="0.5" Brush="{DynamicResource SystemControlForegroundBaseHighBrush}" LineJoin="Round"/>
<Pen Thickness="0.5" Brush="{DynamicResource ControlStrokeColorDefaultBrush}" LineJoin="Round"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingImage.Drawing>
@ -73,7 +73,7 @@
<ControlTheme x:Key="{x:Type TextSelectionHandle}"
TargetType="TextSelectionHandle">
<Setter Property="Background"
Value="{DynamicResource TextControlSelectionHighlightColor}" />
Value="{DynamicResource AccentFillColorDefaultBrush}" />
<Setter Property="HorizontalAlignment"
Value="Center" />
<Setter Property="Template">

5
src/Avalonia.Themes.Fluent2/Controls/Window.xaml

@ -1,8 +1,11 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:ClassModifier="internal">
<!-- No WinUI XAML reference: window chrome is native on Windows. The window canvas
uses the Fluent 2 solid background base fill (#F3F3F3 light / #202020 dark),
matching the WinUI 3 window background. -->
<ControlTheme x:Key="{x:Type Window}" TargetType="Window">
<Setter Property="Background" Value="{DynamicResource SystemRegionBrush}"/>
<Setter Property="Background" Value="{DynamicResource SolidBackgroundFillColorBaseBrush}"/>
<Setter Property="TransparencyBackgroundFallback" Value="{DynamicResource SystemControlBackgroundAltHighBrush}" />
<Setter Property="TopLevel.SystemBarColor" Value="{DynamicResource SystemControlBackgroundAltHighBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource SystemControlForegroundBaseHighBrush}"/>

95
src/Avalonia.Themes.Fluent2/Controls/WindowDrawnDecorations.xaml

@ -2,13 +2,26 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:ClassModifier="internal">
<x:Double x:Key="CaptionButtonWidth">45</x:Double>
<x:Double x:Key="CaptionButtonHeight">30</x:Double>
<!-- No WinUI XAML reference: window chrome is native on Windows. Metrics and colors
follow Windows 11 conventions: 46x32 caption buttons, subtle fills for
hover/pressed, and the #C42B1C close-button hover. -->
<x:Double x:Key="CaptionButtonWidth">46</x:Double>
<x:Double x:Key="CaptionButtonHeight">32</x:Double>
<!-- Windows 11 close caption-button colors; intentionally identical in light and
dark variants, as on Windows. Pressed is the same red at 90% opacity. -->
<SolidColorBrush x:Key="FluentDrawnCaptionButtonCloseBackground" Color="#C42B1C" />
<SolidColorBrush x:Key="FluentDrawnCaptionButtonCloseBackgroundPressed" Color="#C42B1C" Opacity="0.9" />
<SolidColorBrush x:Key="FluentDrawnCaptionButtonCloseForeground" Color="#FFFFFF" />
<!-- Convention: Background carries the hover fill and BorderBrush carries the
pressed fill; the rest state is transparent. Glyphs bind to the button's
Foreground so state changes flow through a single property. -->
<ControlTheme x:Key="FluentDrawnCaptionButton" TargetType="Button">
<Setter Property="Background" Value="{DynamicResource CaptionButtonBackground}" />
<Setter Property="BorderBrush" Value="{DynamicResource CaptionButtonBorderBrush}" />
<Setter Property="Foreground" Value="{DynamicResource CaptionButtonForeground}"/>
<Setter Property="Background" Value="{DynamicResource SubtleFillColorSecondaryBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource SubtleFillColorTertiaryBrush}" />
<Setter Property="Foreground" Value="{DynamicResource TextFillColorPrimaryBrush}"/>
<Setter Property="Width" Value="{DynamicResource CaptionButtonWidth}"/>
<Setter Property="Height" Value="{DynamicResource CaptionButtonHeight}"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
@ -28,10 +41,15 @@
<Style Selector="^:pressed /template/ ContentPresenter">
<Setter Property="Background" Value="{TemplateBinding BorderBrush}" />
</Style>
<!-- Declared last so it overrides the hover/pressed fills at equal priority -->
<Style Selector="^:disabled /template/ ContentPresenter">
<Setter Property="Background" Value="Transparent" />
</Style>
</ControlTheme>
<ControlTheme x:Key="{x:Type WindowDrawnDecorations}" TargetType="WindowDrawnDecorations">
<Setter Property="DefaultTitleBarHeight" Value="30"/>
<Setter Property="DefaultTitleBarHeight" Value="32"/>
<Setter Property="DefaultFrameThickness" Value="1"/>
<Setter Property="DefaultShadowThickness" Value="8"/>
<Setter Property="Template">
@ -43,12 +61,13 @@
<Border x:Name="PART_WindowBorder"
Background="{DynamicResource SystemControlTransparentBrush}"
BorderThickness="{TemplateBinding FrameThickness}"
BorderBrush="{DynamicResource SystemControlForegroundBaseMediumBrush}"
BorderBrush="{DynamicResource SurfaceStrokeColorDefaultBrush}"
IsHitTestVisible="False" />
<!-- Titlebar: background, title text, and drag area live in underlay -->
<!-- Titlebar: background, title text, and drag area live in underlay.
Matches the window canvas, as on Windows 11. -->
<Panel x:Name="PART_TitleBar" VerticalAlignment="Top"
Height="{TemplateBinding TitleBarHeight}"
Background="{DynamicResource TitleBarBackgroundBrush}"
Background="{DynamicResource SolidBackgroundFillColorBaseBrush}"
IsVisible="{TemplateBinding HasTitleBar}"
WindowDecorationProperties.ElementRole="TitleBar" />
@ -64,6 +83,7 @@
IsHitTestVisible="False"
IsVisible="{TemplateBinding HasTitleBar}">
<TextBlock Text="{TemplateBinding Title}"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
VerticalAlignment="Center"
Margin="12,0,0,0"
FontSize="12" />
@ -74,48 +94,48 @@
Height="{TemplateBinding TitleBarHeight}"
IsVisible="{TemplateBinding HasTitleBar}"
Orientation="Horizontal"
Spacing="2"
Spacing="0"
TextElement.FontSize="10">
<Button x:Name="PART_FullScreenButton"
Theme="{StaticResource FluentDrawnCaptionButton}"
WindowDecorationProperties.ElementRole="FullScreenButton">
<Viewbox Width="11" Margin="2">
<Viewbox Width="10">
<Path Name="FullScreenButtonPath"
Stretch="UniformToFill"
Fill="{DynamicResource CaptionButtonForeground}"
Fill="{Binding $parent[Button].Foreground}"
Data="M2048 2048v-819h-205v469l-1493 -1493h469v-205h-819v819h205v-469l1493 1493h-469v205h819z" />
</Viewbox>
</Button>
<Button x:Name="PART_MinimizeButton"
Theme="{StaticResource FluentDrawnCaptionButton}"
WindowDecorationProperties.ElementRole="MinimizeButton">
<Viewbox Width="11" Margin="2">
<Viewbox Width="10">
<Path Stretch="UniformToFill"
Fill="{DynamicResource CaptionButtonForeground}"
Fill="{Binding $parent[Button].Foreground}"
Data="M2048 1229v-205h-2048v205h2048z" />
</Viewbox>
</Button>
<Button x:Name="PART_MaximizeButton"
Theme="{StaticResource FluentDrawnCaptionButton}"
WindowDecorationProperties.ElementRole="MaximizeButton">
<Viewbox Width="11" Margin="2">
<Viewbox Width="10">
<Viewbox.RenderTransform>
<RotateTransform Angle="-90" />
</Viewbox.RenderTransform>
<Path Name="RestoreButtonPath"
Stretch="UniformToFill"
Fill="{DynamicResource CaptionButtonForeground}"
Fill="{Binding $parent[Button].Foreground}"
Data="M2048 2048v-2048h-2048v2048h2048zM1843 1843h-1638v-1638h1638v1638z"/>
</Viewbox>
</Button>
<Button x:Name="PART_CloseButton"
Background="#ffe81123"
BorderBrush="#fff1707a"
Background="{StaticResource FluentDrawnCaptionButtonCloseBackground}"
BorderBrush="{StaticResource FluentDrawnCaptionButtonCloseBackgroundPressed}"
Theme="{StaticResource FluentDrawnCaptionButton}"
WindowDecorationProperties.ElementRole="CloseButton">
<Viewbox Width="11" Margin="2">
<Viewbox Width="10">
<Path Stretch="UniformToFill"
Fill="{DynamicResource CaptionButtonForeground}"
Fill="{Binding $parent[Button].Foreground}"
Data="M1169 1024l879 -879l-145 -145l-879 879l-879 -879l-145 145l879 879l-879 879l145 145l879 -879l879 879l145 -145z" />
</Viewbox>
</Button>
@ -126,33 +146,34 @@
<WindowDrawnDecorationsContent.FullscreenPopover>
<Panel Height="{TemplateBinding DefaultTitleBarHeight}"
VerticalAlignment="Top"
Background="{DynamicResource SystemControlBackgroundChromeMediumLowBrush}"
Background="{DynamicResource SolidBackgroundFillColorBaseBrush}"
WindowDecorationProperties.ElementRole="TitleBar">
<TextBlock Text="{TemplateBinding Title}"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
VerticalAlignment="Center"
Margin="12,0,0,0"
FontSize="12" />
<StackPanel HorizontalAlignment="Right"
Orientation="Horizontal"
Spacing="2"
Spacing="0"
TextElement.FontSize="10">
<Button x:Name="PART_PopoverFullScreenButton"
Theme="{StaticResource FluentDrawnCaptionButton}"
WindowDecorationProperties.ElementRole="FullScreenButton">
<Viewbox Width="11" Margin="2">
<Viewbox Width="10">
<Path Stretch="UniformToFill"
Fill="{DynamicResource CaptionButtonForeground}"
Fill="{Binding $parent[Button].Foreground}"
Data="M205 1024h819v-819h-205v469l-674 -674l-145 145l674 674h-469v205zM1374 1229h469v-205h-819v819h205v-469l674 674l145 -145z" />
</Viewbox>
</Button>
<Button x:Name="PART_PopoverCloseButton"
Background="#ffe81123"
BorderBrush="#fff1707a"
Background="{StaticResource FluentDrawnCaptionButtonCloseBackground}"
BorderBrush="{StaticResource FluentDrawnCaptionButtonCloseBackgroundPressed}"
Theme="{StaticResource FluentDrawnCaptionButton}"
WindowDecorationProperties.ElementRole="CloseButton">
<Viewbox Width="11" Margin="2">
<Viewbox Width="10">
<Path Stretch="UniformToFill"
Fill="{DynamicResource CaptionButtonForeground}"
Fill="{Binding $parent[Button].Foreground}"
Data="M1169 1024l879 -879l-145 -145l-879 879l-879 -879l-145 145l879 879l-879 879l145 145l879 -879l879 879l145 -145z" />
</Viewbox>
</Button>
@ -190,10 +211,24 @@
<Style Selector="^:maximized /template/ Path#RestoreButtonPath">
<Setter Property="Data" Value="M2048 410h-410v-410h-1638v1638h410v410h1638v-1638zM1434 1434h-1229v-1229h1229v1229zM1843 1843h-1229v-205h1024v-1024h205v1229z" />
</Style>
<!-- Close button: white glyph over the Windows 11 red fill while hovered/pressed -->
<Style Selector="^ /template/ Button#PART_CloseButton:pointerover">
<Setter Property="Foreground" Value="{StaticResource FluentDrawnCaptionButtonCloseForeground}"/>
</Style>
<Style Selector="^ /template/ Button#PART_CloseButton:pressed">
<Setter Property="Foreground" Value="{StaticResource FluentDrawnCaptionButtonCloseForeground}"/>
</Style>
<Style Selector="^ /template/ Button#PART_PopoverCloseButton:pointerover">
<Setter Property="Foreground" Value="{StaticResource FluentDrawnCaptionButtonCloseForeground}"/>
</Style>
<Style Selector="^ /template/ Button#PART_PopoverCloseButton:pressed">
<Setter Property="Foreground" Value="{StaticResource FluentDrawnCaptionButtonCloseForeground}"/>
</Style>
<!-- Disabled buttons -->
<Style Selector="^ /template/ Button:disabled">
<Setter Property="Opacity" Value="0.2"/>
<Setter Property="Foreground" Value="{DynamicResource TextFillColorDisabledBrush}"/>
</Style>
<!-- Hide caption buttons when the platform does not support the action -->

30
src/Avalonia.Themes.Fluent2/Controls/WindowNotificationManager.xaml

@ -2,30 +2,42 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:DataType="WindowNotificationManager"
x:ClassModifier="internal">
<!-- WinUI reference: InfoBar_themeresources.xaml, winui3/release/1.4.2 (via Uno.UI.FluentTheme.v2).
Stack metrics follow the WinUI teaching-tip/notification idiom: 8px gap between cards, 16px inset
from the window edges. Title/message typography per InfoBar: title SemiBold 14 TextFillColorPrimary
(InfoBarTitleFontWeight/FontSize), message 14 (message uses TextFillColorSecondary here — WinUI
InfoBar uses Primary for both; see conversion notes). Vertical InfoBarPanel margins: title 0,14,0,0,
message +4, 16 bottom padding. Horizontal padding comes from the NotificationCard template. -->
<ControlTheme x:Key="{x:Type WindowNotificationManager}" TargetType="WindowNotificationManager">
<Setter Property="Margin" Value="0 0" />
<Setter Property="Template">
<ControlTemplate>
<ReversibleStackPanel Name="PART_Items">
<ReversibleStackPanel Name="PART_Items" Margin="16" Spacing="8">
<ReversibleStackPanel.DataTemplates>
<DataTemplate DataType="INotification">
<StackPanel
Margin="12"
Spacing="8"
TextElement.Foreground="{DynamicResource SystemControlForegroundBaseHighBrush}">
<TextBlock FontWeight="Medium" Text="{Binding Title}" />
Margin="0,14,0,16"
Spacing="4"
TextElement.Foreground="{DynamicResource TextFillColorPrimaryBrush}">
<TextBlock FontWeight="SemiBold"
FontSize="14"
Text="{Binding Title}"
TextWrapping="Wrap" />
<TextBlock
MaxHeight="80"
Margin="0,0,12,0"
FontSize="14"
Foreground="{DynamicResource TextFillColorSecondaryBrush}"
Text="{Binding Message}"
TextWrapping="Wrap" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="x:String">
<TextBlock
Margin="12"
Foreground="{DynamicResource SystemControlForegroundBaseHighBrush}"
Text="{Binding}" />
Margin="0,14,0,14"
FontSize="14"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
Text="{Binding}"
TextWrapping="Wrap" />
</DataTemplate>
</ReversibleStackPanel.DataTemplates>
</ReversibleStackPanel>

20
src/Avalonia.Themes.Fluent2/DensityStyles/Compact.xaml

@ -1,15 +1,25 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:ClassModifier="internal">
<x:Double x:Key="ControlContentThemeFontSize">14</x:Double>
<x:Double x:Key="TextControlThemeMinHeight">24</x:Double>
<x:Double x:Key="TextControlThemeMinWidth">32</x:Double>
<Thickness x:Key="TextControlThemePadding">4, 2</Thickness>
<Thickness x:Key="ListBoxItemPadding">4,2</Thickness>
<!-- Base 10,5,6,6: horizontal kept so text stays aligned with ComboBox/Button; vertical trimmed to 1/3
so a 20px text line fits the 24px compact min-height (same 1/3 rhythm as compact ComboBoxPadding). -->
<Thickness x:Key="TextControlThemePadding">10,1,6,3</Thickness>
<!-- Base 12,0,12,0: v1's -8 horizontal trim applied; vertical stays 0 because the Fluent 2 row height
comes from ListBoxItemMinHeight (defined locally in Controls/ListBoxItem.xaml, not overridable here). -->
<x:Double x:Key="ListBoxItemMinHeight">24</x:Double>
<Thickness x:Key="ListBoxItemPadding">4,0,4,0</Thickness>
<x:Double x:Key="ListViewItemMinHeight">24</x:Double>
<!-- Unchanged from base 11,5,11,7 (v1 compact did not reduce this key either). -->
<Thickness x:Key="ComboBoxItemThemePadding">11,5,11,7</Thickness>
<!-- Base 11,4,11,5: vertical normalized to 4 (v1 did the same from 4/7); horizontal tightened as in v1. -->
<Thickness x:Key="MenuFlyoutItemThemePaddingNarrow">4 4 8 4</Thickness>
<!-- Half of the Fluent 2 base 10,4 - happens to equal the v1 compact value. -->
<Thickness x:Key="MenuBarItemPadding">5, 2</Thickness>
<!-- Base dropped 32 -> 28 in Fluent 2; held at the 24px compact floor shared by the other item heights
(the raw -8 delta would give 20, i.e. bare line height with no breathing room). -->
<x:Double x:Key="TreeViewItemMinHeight">24</x:Double>
<Thickness x:Key="TimePickerHostPadding">0,1,0,2</Thickness>
<Thickness x:Key="DatePickerHostPadding">0,1,0,2</Thickness>
@ -20,7 +30,9 @@
<x:Double x:Key="NavigationViewItemOnLeftMinHeight">32</x:Double>
<x:Double x:Key="TabItemMinHeight">28</x:Double>
<Thickness x:Key="TabItemHeaderMargin">6, 0</Thickness>
<Thickness x:Key="ButtonPadding">6,4</Thickness>
<!-- v1 trimmed 8,5,8,6 -> 6,4; the same trim on the Fluent 2 base 11,5,11,6 gives 9,4
(a 28px compact button: 20px line + 4 + 4, matching v1's compact button height). -->
<Thickness x:Key="ButtonPadding">9,4</Thickness>
<x:Double x:Key="CheckBoxMinHeight">24</x:Double>
<x:Double x:Key="RadioButtonMinHeight">24</x:Double>
</ResourceDictionary>

Loading…
Cancel
Save