diff --git a/demo/Ursa.Demo/Models/MenuKeys.cs b/demo/Ursa.Demo/Models/MenuKeys.cs
index 085be94..b7b1a76 100644
--- a/demo/Ursa.Demo/Models/MenuKeys.cs
+++ b/demo/Ursa.Demo/Models/MenuKeys.cs
@@ -6,6 +6,7 @@ public static class MenuKeys
public const string MenuKeyBadge = "Badge";
public const string MenuKeyBanner = "Banner";
public const string MenuKeyButtonGroup = "ButtonGroup";
+ public const string MenuKeyBreadcrumb = "Breadcrumb";
public const string MenuKeyClassInput = "Class Input";
public const string MenuKeyDialog = "Dialog";
public const string MenuKeyDivider = "Divider";
diff --git a/demo/Ursa.Demo/Pages/BreadcrumbDemo.axaml b/demo/Ursa.Demo/Pages/BreadcrumbDemo.axaml
new file mode 100644
index 0000000..101542e
--- /dev/null
+++ b/demo/Ursa.Demo/Pages/BreadcrumbDemo.axaml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/Ursa.Demo/Pages/BreadcrumbDemo.axaml.cs b/demo/Ursa.Demo/Pages/BreadcrumbDemo.axaml.cs
new file mode 100644
index 0000000..c119fc7
--- /dev/null
+++ b/demo/Ursa.Demo/Pages/BreadcrumbDemo.axaml.cs
@@ -0,0 +1,13 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace Ursa.Demo.Pages;
+
+public partial class BreadcrumbDemo : UserControl
+{
+ public BreadcrumbDemo()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/demo/Ursa.Demo/ViewModels/BreadcrumbDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/BreadcrumbDemoViewModel.cs
new file mode 100644
index 0000000..d5dbbee
--- /dev/null
+++ b/demo/Ursa.Demo/ViewModels/BreadcrumbDemoViewModel.cs
@@ -0,0 +1,41 @@
+using System.Collections.ObjectModel;
+using System.Windows.Input;
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using Ursa.Controls;
+
+namespace Ursa.Demo.ViewModels;
+
+public class BreadcrumbDemoViewModel: ObservableObject
+{
+ public ObservableCollection Items1 { get; set; }
+
+ public BreadcrumbDemoViewModel()
+ {
+ Items1 = new ObservableCollection()
+ {
+ new BreadcrumbDemoItem() { Section = "Home", Icon = "Home" },
+ new BreadcrumbDemoItem() { Section = "Page 1", Icon = "Page" },
+ new BreadcrumbDemoItem() { Section = "Page 2", Icon = "Page" },
+ new BreadcrumbDemoItem() { Section = "Page 3", Icon = "Page" },
+ new BreadcrumbDemoItem() { Section = "Page 4", Icon = "Page", IsReadOnly = true},
+ };
+ }
+}
+
+public partial class BreadcrumbDemoItem: ObservableObject
+{
+ public string Section { get; set; }
+ public string Icon { get; set; }
+ [ObservableProperty] private bool _isReadOnly;
+
+ public ICommand Command { get; set; }
+
+ public BreadcrumbDemoItem()
+ {
+ Command = new RelayCommand(() =>
+ {
+ MessageBox.ShowOverlayAsync(Section);
+ });
+ }
+}
\ No newline at end of file
diff --git a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs
index 8cc13e6..d987128 100644
--- a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs
+++ b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs
@@ -28,6 +28,7 @@ public class MainViewViewModel : ViewModelBase
MenuKeys.MenuKeyBadge => new BadgeDemoViewModel(),
MenuKeys.MenuKeyBanner => new BannerDemoViewModel(),
MenuKeys.MenuKeyButtonGroup => new ButtonGroupDemoViewModel(),
+ MenuKeys.MenuKeyBreadcrumb => new BreadcrumbDemoViewModel(),
MenuKeys.MenuKeyClassInput => new ClassInputDemoViewModel(),
MenuKeys.MenuKeyDialog => new DialogDemoViewModel(),
MenuKeys.MenuKeyDivider => new DividerDemoViewModel(),
diff --git a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs
index a25e8d1..a4eaa14 100644
--- a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs
+++ b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs
@@ -14,6 +14,7 @@ public class MenuViewModel: ViewModelBase
new() { MenuHeader = "Controls", IsSeparator = true },
new() { MenuHeader = "Badge", Key = MenuKeys.MenuKeyBadge, Status = "Updated"},
new() { MenuHeader = "Banner", Key = MenuKeys.MenuKeyBanner },
+ new() { MenuHeader = "Breadcrumb", Key = MenuKeys.MenuKeyBreadcrumb, Status = "New" },
new() { MenuHeader = "Button Group", Key = MenuKeys.MenuKeyButtonGroup},
new() { MenuHeader = "Class Input", Key = MenuKeys.MenuKeyClassInput, Status = "New" },
new() { MenuHeader = "Dialog", Key = MenuKeys.MenuKeyDialog, Status = "Updated"},
diff --git a/src/Ursa.Themes.Semi/Controls/Breadcrumb.axaml b/src/Ursa.Themes.Semi/Controls/Breadcrumb.axaml
new file mode 100644
index 0000000..4df2747
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Controls/Breadcrumb.axaml
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Ursa.Themes.Semi/Controls/_index.axaml b/src/Ursa.Themes.Semi/Controls/_index.axaml
index 21d3909..6be2414 100644
--- a/src/Ursa.Themes.Semi/Controls/_index.axaml
+++ b/src/Ursa.Themes.Semi/Controls/_index.axaml
@@ -4,6 +4,7 @@
+
diff --git a/src/Ursa.Themes.Semi/Styles/Breadcrumb.axaml b/src/Ursa.Themes.Semi/Styles/Breadcrumb.axaml
new file mode 100644
index 0000000..66e6706
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Styles/Breadcrumb.axaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Ursa.Themes.Semi/Styles/_index.axaml b/src/Ursa.Themes.Semi/Styles/_index.axaml
index e3cc666..baa0d9b 100644
--- a/src/Ursa.Themes.Semi/Styles/_index.axaml
+++ b/src/Ursa.Themes.Semi/Styles/_index.axaml
@@ -4,6 +4,7 @@
+
diff --git a/src/Ursa/Controls/BackTop/BackTop.cs b/src/Ursa/Controls/BackTop/BackTop.cs
new file mode 100644
index 0000000..3506807
--- /dev/null
+++ b/src/Ursa/Controls/BackTop/BackTop.cs
@@ -0,0 +1,15 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.Primitives;
+using Avalonia.Media;
+
+namespace Ursa.Controls.BackTop;
+
+public class BackTop: Control
+{
+ public static readonly AttachedProperty AttachProperty =
+ AvaloniaProperty.RegisterAttached("Attach");
+
+ public static void SetAttach(Control obj, bool value) => obj.SetValue(AttachProperty, value);
+ public static bool GetAttach(Control obj) => obj.GetValue(AttachProperty);
+}
\ No newline at end of file
diff --git a/src/Ursa/Controls/Breadcrumb/Breadcrumb.cs b/src/Ursa/Controls/Breadcrumb/Breadcrumb.cs
new file mode 100644
index 0000000..4818d40
--- /dev/null
+++ b/src/Ursa/Controls/Breadcrumb/Breadcrumb.cs
@@ -0,0 +1,128 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.Templates;
+using Avalonia.Data;
+using Avalonia.Layout;
+using Avalonia.Metadata;
+
+namespace Ursa.Controls;
+
+public class Breadcrumb: ItemsControl
+{
+ private static readonly ITemplate _defaultPanel =
+ new FuncTemplate(() => new StackPanel() { Orientation = Orientation.Horizontal });
+
+
+ public static readonly StyledProperty IconBindingProperty = AvaloniaProperty.Register(
+ nameof(IconBinding));
+
+ [AssignBinding]
+ [InheritDataTypeFromItems(nameof(ItemsSource))]
+ public IBinding? IconBinding
+ {
+ get => GetValue(IconBindingProperty);
+ set => SetValue(IconBindingProperty, value);
+ }
+
+ public static readonly StyledProperty CommandBindingProperty = AvaloniaProperty.Register(
+ nameof(CommandBinding));
+
+ [AssignBinding]
+ [InheritDataTypeFromItems(nameof(ItemsSource))]
+ public IBinding? CommandBinding
+ {
+ get => GetValue(CommandBindingProperty);
+ set => SetValue(CommandBindingProperty, value);
+ }
+
+ public static readonly StyledProperty