diff --git a/src/Files.App.Controls/ThemedIcon/Data/ThemedIconColorType.cs b/src/Files.App.Controls/ThemedIcon/Data/ThemedIconColorType.cs
new file mode 100644
index 000000000000..f4f4c67c2da4
--- /dev/null
+++ b/src/Files.App.Controls/ThemedIcon/Data/ThemedIconColorType.cs
@@ -0,0 +1,50 @@
+// Copyright (c) 2024 Files Community
+// Licensed under the MIT License. See the LICENSE.
+
+namespace Files.App.Controls
+{
+ ///
+ /// Defines the IconColorTypes for which sets the visual state
+ /// to use the correct brush values which match system signal colors.
+ ///
+ public enum ThemedIconColorType
+ {
+ None,
+
+ ///
+ /// Icon color type of is Normal. Default Value.
+ ///
+ Normal,
+
+ ///
+ /// Icon color type of is Critical.
+ ///
+ Critical,
+
+ ///
+ /// Icon color type of is Caution.
+ ///
+ Caution,
+
+ ///
+ /// Icon color type of is Success.
+ ///
+ Success,
+
+ ///
+ /// Icon color type of is Neutral.
+ ///
+ Neutral,
+
+ ///
+ /// Icon color type of is Accent.
+ ///
+ Accent,
+
+ ///
+ /// Icon color type of is Custom. Used in combination
+ /// with the IconColor and Foreground brushes.
+ ///
+ Custom
+ }
+}
diff --git a/src/Files.App.Controls/ThemedIcon/Data/ThemedIconLayerType.cs b/src/Files.App.Controls/ThemedIcon/Data/ThemedIconLayerType.cs
new file mode 100644
index 000000000000..ac4ef314b8d6
--- /dev/null
+++ b/src/Files.App.Controls/ThemedIcon/Data/ThemedIconLayerType.cs
@@ -0,0 +1,28 @@
+// Copyright (c) 2024 Files Community
+// Licensed under the MIT License. See the LICENSE.
+
+namespace Files.App.Controls
+{
+ ///
+ /// Defines LayerTypes for .
+ ///
+ public enum ThemedIconLayerType
+ {
+ ///
+ /// The LayerType uses the Base color. Default state.
+ ///
+ Base,
+ ///
+ /// The LayerType uses the Alt color.
+ ///
+ Alt,
+ ///
+ /// The LayerType uses an Accented color.
+ ///
+ Accent,
+ ///
+ /// The LayerType uses a contrasting color for the Accented color.
+ ///
+ AccentContrast,
+ }
+}
diff --git a/src/Files.App.Controls/ThemedIcon/Data/ThemedIconLayers.cs b/src/Files.App.Controls/ThemedIcon/Data/ThemedIconLayers.cs
new file mode 100644
index 000000000000..653670046591
--- /dev/null
+++ b/src/Files.App.Controls/ThemedIcon/Data/ThemedIconLayers.cs
@@ -0,0 +1,12 @@
+// Copyright (c) 2024 Files Community
+// Licensed under the MIT License. See the LICENSE.
+
+namespace Files.App.Controls
+{
+ ///
+ /// A collection of Layers for the ThemedIcon's Layered IconType
+ ///
+ public sealed class ThemedIconLayers : List
+ {
+ }
+}
diff --git a/src/Files.App.Controls/ThemedIcon/Data/ThemedIconToggleBehaviors.cs b/src/Files.App.Controls/ThemedIcon/Data/ThemedIconToggleBehaviors.cs
new file mode 100644
index 000000000000..3490f15a1da4
--- /dev/null
+++ b/src/Files.App.Controls/ThemedIcon/Data/ThemedIconToggleBehaviors.cs
@@ -0,0 +1,26 @@
+// Copyright (c) 2024 Files Community
+// Licensed under the MIT License. See the LICENSE.
+
+namespace Files.App.Controls
+{
+ ///
+ /// Defines IconTypes for .
+ ///
+ public enum ToggleBehaviors
+ {
+ ///
+ /// Auto enables the ThemedIcon to listen to owner control states.
+ ///
+ Auto,
+
+ ///
+ /// On will always use the ThemedIcon's Toggle state
+ ///
+ On,
+
+ ///
+ /// Off will not use the ThemedIcon's Toggle state
+ ///
+ Off,
+ }
+}
diff --git a/src/Files.App.Controls/ThemedIcon/Data/ThemedIconTypes.cs b/src/Files.App.Controls/ThemedIcon/Data/ThemedIconTypes.cs
new file mode 100644
index 000000000000..58299f1d61fd
--- /dev/null
+++ b/src/Files.App.Controls/ThemedIcon/Data/ThemedIconTypes.cs
@@ -0,0 +1,21 @@
+// Copyright (c) 2024 Files Community
+// Licensed under the MIT License. See the LICENSE.
+
+namespace Files.App.Controls
+{
+ ///
+ /// Defines IconTypes for .
+ ///
+ public enum ThemedIconTypes
+ {
+ ///
+ /// Icon type of is Outline.
+ ///
+ Outline,
+
+ ///
+ /// Icon type of is Layered.
+ ///
+ Layered,
+ }
+}
diff --git a/src/Files.App.Controls/ThemedIcon/ThemedIcon.Consts.cs b/src/Files.App.Controls/ThemedIcon/ThemedIcon.Consts.cs
index fb3388f3c4c1..b674c25d1432 100644
--- a/src/Files.App.Controls/ThemedIcon/ThemedIcon.Consts.cs
+++ b/src/Files.App.Controls/ThemedIcon/ThemedIcon.Consts.cs
@@ -6,69 +6,65 @@
namespace Files.App.Controls
{
- // Template Parts
- [TemplatePart(Name = FilledPathIconViewBox, Type = typeof(Viewbox))]
- [TemplatePart(Name = OutlinePathIconViewBox, Type = typeof(Viewbox))]
- [TemplatePart(Name = LayeredPathIconViewBox, Type = typeof(Viewbox))]
- [TemplatePart(Name = LayeredPathCanvas, Type = typeof(Canvas))]
-
- // Icon Type Visual States
- [TemplateVisualState(Name = OutlineTypeStateName, GroupName = IconTypeStateGroupName)]
- [TemplateVisualState(Name = LayeredTypeStateName, GroupName = IconTypeStateGroupName)]
- [TemplateVisualState(Name = FilledTypeStateName, GroupName = IconTypeStateGroupName)]
+ // Template Parts
+ [TemplatePart(Name = FilledPathIconViewBox, Type = typeof(Viewbox))]
+ [TemplatePart(Name = OutlinePathIconViewBox, Type = typeof(Viewbox))]
+ [TemplatePart(Name = LayeredPathIconViewBox, Type = typeof(Viewbox))]
+ [TemplatePart(Name = LayeredPathCanvas, Type = typeof(Canvas))]
+ // Icon Type Visual States
+ [TemplateVisualState(Name = OutlineTypeStateName, GroupName = IconTypeStateGroupName)]
+ [TemplateVisualState(Name = LayeredTypeStateName, GroupName = IconTypeStateGroupName)]
+ [TemplateVisualState(Name = FilledTypeStateName, GroupName = IconTypeStateGroupName)]
+ // Icon Color Visual States
+ [TemplateVisualState(Name = NormalStateName, GroupName = IconColorStateGroupName)]
+ [TemplateVisualState(Name = CriticalStateName, GroupName = IconColorStateGroupName)]
+ [TemplateVisualState(Name = CautionStateName, GroupName = IconColorStateGroupName)]
+ [TemplateVisualState(Name = SuccessStateName, GroupName = IconColorStateGroupName)]
+ [TemplateVisualState(Name = NeutralStateName, GroupName = IconColorStateGroupName)]
+ [TemplateVisualState(Name = AccentStateName, GroupName = IconColorStateGroupName)]
+ [TemplateVisualState(Name = CustomColorStateName, GroupName = IconColorStateGroupName)]
+ [TemplateVisualState(Name = ToggleStateName, GroupName = IconColorStateGroupName)]
+ [TemplateVisualState(Name = DisabledColorStateName, GroupName = IconColorStateGroupName)]
+ [TemplateVisualState(Name = DisabledToggleColorStateName, GroupName = IconColorStateGroupName)]
+ // Icon IsEnabled Visual States
+ [TemplateVisualState(Name = EnabledStateName, GroupName = EnabledStateGroupName)]
+ [TemplateVisualState(Name = DisabledStateName, GroupName = EnabledStateGroupName)]
+ public partial class ThemedIcon
+ {
+ // Visual State Group Names
+ internal const string IconTypeStateGroupName = "IconTypeStates";
+ internal const string IconColorStateGroupName = "IconColorStates";
+ internal const string EnabledStateGroupName = "EnabledStates";
- // Icon Color Visual States
- [TemplateVisualState(Name = NormalStateName, GroupName = IconColorStateGroupName)]
- [TemplateVisualState(Name = CriticalStateName, GroupName = IconColorStateGroupName)]
- [TemplateVisualState(Name = CautionStateName, GroupName = IconColorStateGroupName)]
- [TemplateVisualState(Name = SuccessStateName, GroupName = IconColorStateGroupName)]
- [TemplateVisualState(Name = NeutralStateName, GroupName = IconColorStateGroupName)]
- [TemplateVisualState(Name = AccentStateName, GroupName = IconColorStateGroupName)]
- [TemplateVisualState(Name = CustomColorStateName, GroupName = IconColorStateGroupName)]
- [TemplateVisualState(Name = ToggleStateName, GroupName = IconColorStateGroupName)]
- [TemplateVisualState(Name = DisabledColorStateName, GroupName = IconColorStateGroupName)]
- [TemplateVisualState(Name = DisabledToggleColorStateName, GroupName = IconColorStateGroupName)]
+ // "Icon Type" Visual State Names
+ internal const string OutlineTypeStateName = "Outline";
+ internal const string FilledTypeStateName = "Filled";
+ internal const string LayeredTypeStateName = "Layered";
- // Icon IsEnabled Visual States
- [TemplateVisualState(Name = EnabledStateName, GroupName = EnabledStateGroupName)]
- [TemplateVisualState(Name = DisabledStateName, GroupName = EnabledStateGroupName)]
+ // "Icon State" Visual State Names
+ internal const string NormalStateName = "Normal";
+ internal const string CriticalStateName = "Critical";
+ internal const string CautionStateName = "Caution";
+ internal const string SuccessStateName = "Success";
+ internal const string NeutralStateName = "Neutral";
+ internal const string AccentStateName = "Accent";
+ internal const string CustomColorStateName = "Custom";
+ internal const string ToggleStateName = "Toggle";
+ internal const string DisabledColorStateName = "DisabledColor";
+ internal const string DisabledToggleColorStateName = "DisabledToggleColor";
- public partial class ThemedIcon
- {
- // Visual State Group Names
- internal const string IconTypeStateGroupName = "IconTypeStates";
- internal const string IconColorStateGroupName = "IconColorStates";
- internal const string EnabledStateGroupName = "EnabledStates";
+ // "Enabled" Visual State Names
+ internal const string EnabledStateName = "Enabled";
+ internal const string DisabledStateName = "Disabled";
- // "Icon Type" Visual State Names
- internal const string OutlineTypeStateName = "Outline";
- internal const string FilledTypeStateName = "Filled";
- internal const string LayeredTypeStateName = "Layered";
+ // ViewBox Controls
+ internal const string FilledPathIconViewBox = "PART_FilledIconViewBox";
+ internal const string OutlinePathIconViewBox = "PART_OutlineIconViewBox";
+ internal const string LayeredPathIconViewBox = "PART_LayeredIconViewBox";
+ internal const string LayeredPathCanvas = "PART_LayerCanvas";
- // "Icon State" Visual State Names
- internal const string NormalStateName = "Normal";
- internal const string CriticalStateName = "Critical";
- internal const string CautionStateName = "Caution";
- internal const string SuccessStateName = "Success";
- internal const string NeutralStateName = "Neutral";
- internal const string AccentStateName = "Accent";
- internal const string CustomColorStateName = "Custom";
- internal const string ToggleStateName = "Toggle";
- internal const string DisabledColorStateName = "DisabledColor";
- internal const string DisabledToggleColorStateName = "DisabledToggleColor";
-
- // "Enabled" Visual State Names
- internal const string EnabledStateName = "Enabled";
- internal const string DisabledStateName = "Disabled";
-
- // ViewBox Controls
- internal const string FilledPathIconViewBox = "PART_FilledIconViewBox";
- internal const string OutlinePathIconViewBox = "PART_OutlineIconViewBox";
- internal const string LayeredPathIconViewBox = "PART_LayeredIconViewBox";
- internal const string LayeredPathCanvas = "PART_LayerCanvas";
-
- // Path Controls
- internal const string FilledIconPath = "PART_FilledPath";
- internal const string OutlineIconPath = "PART_OutlinePath";
- }
-}
\ No newline at end of file
+ // Path Controls
+ internal const string FilledIconPath = "PART_FilledPath";
+ internal const string OutlineIconPath = "PART_OutlinePath";
+ }
+}
diff --git a/src/Files.App.Controls/ThemedIcon/ThemedIcon.Owner.cs b/src/Files.App.Controls/ThemedIcon/ThemedIcon.Owner.cs
new file mode 100644
index 000000000000..95770e40025c
--- /dev/null
+++ b/src/Files.App.Controls/ThemedIcon/ThemedIcon.Owner.cs
@@ -0,0 +1,62 @@
+// Copyright (c) 2024 Files Community
+// Licensed under the MIT License. See the LICENSE.
+
+using CommunityToolkit.WinUI.UI;
+using Microsoft.UI.Xaml;
+using Microsoft.UI.Xaml.Controls;
+using Microsoft.UI.Xaml.Controls.Primitives;
+
+namespace Files.App.Controls
+{
+ public partial class ThemedIcon
+ {
+ private bool _isOwnerToggled;
+ private bool _isOwnerEnabled;
+
+ private Control? ownerControl = null;
+ private ToggleButton? ownerToggleButton = null;
+
+ private void FindOwnerControlStates()
+ {
+ if (this.FindAscendant() is ToggleButton toggleButton)
+ {
+ ownerToggleButton = toggleButton;
+
+ // IsChecked/IsToggled change aware
+ ownerToggleButton.Checked += OwnerControl_IsCheckedChanged;
+ ownerToggleButton.Unchecked += OwnerControl_IsCheckedChanged;
+ _isOwnerToggled = ownerToggleButton.IsChecked is true;
+ }
+
+ if (this.FindAscendant() is Control control)
+ {
+ ownerControl = control;
+
+ // IsEnabled change aware
+ ownerControl.IsEnabledChanged += OwnerControl_IsEnabledChanged;
+ _isOwnerEnabled = ownerControl.IsEnabled;
+
+ UpdateVisualStates();
+ }
+ }
+
+ private void OwnerControl_IsCheckedChanged(object sender, RoutedEventArgs e)
+ {
+ if (ownerToggleButton is null)
+ return;
+
+ _isOwnerToggled = ownerToggleButton.IsChecked is true;
+ UpdateVisualStates();
+
+ }
+
+ private void OwnerControl_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
+ {
+ if (ownerControl is null)
+ return;
+
+ _isOwnerEnabled = ownerControl.IsEnabled;
+ UpdateVisualStates();
+ }
+ }
+}
diff --git a/src/Files.App.Controls/ThemedIcon/ThemedIcon.Properties.cs b/src/Files.App.Controls/ThemedIcon/ThemedIcon.Properties.cs
index 0562d2409f0e..a6c1d8ecc5c5 100644
--- a/src/Files.App.Controls/ThemedIcon/ThemedIcon.Properties.cs
+++ b/src/Files.App.Controls/ThemedIcon/ThemedIcon.Properties.cs
@@ -16,56 +16,62 @@ namespace Files.App.Controls
[DependencyProperty("IsFilled", nameof(OnIsFilledPropertyChanged), DefaultValue = "false")]
[DependencyProperty("IsHighContrast", nameof(OnIsHighContrastPropertyChanged), DefaultValue = "false")]
[DependencyProperty