diff --git a/demo/Ursa.Demo/Pages/LoadingDemo.axaml b/demo/Ursa.Demo/Pages/LoadingDemo.axaml
new file mode 100644
index 0000000..00c0fb9
--- /dev/null
+++ b/demo/Ursa.Demo/Pages/LoadingDemo.axaml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/Ursa.Demo/Pages/LoadingDemo.axaml.cs b/demo/Ursa.Demo/Pages/LoadingDemo.axaml.cs
new file mode 100644
index 0000000..cfbc0e8
--- /dev/null
+++ b/demo/Ursa.Demo/Pages/LoadingDemo.axaml.cs
@@ -0,0 +1,18 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace Ursa.Demo.Pages;
+
+public partial class LoadingDemo : UserControl
+{
+ public LoadingDemo()
+ {
+ InitializeComponent();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+}
\ No newline at end of file
diff --git a/demo/Ursa.Demo/Views/MainWindow.axaml b/demo/Ursa.Demo/Views/MainWindow.axaml
index 230667b..ee33626 100644
--- a/demo/Ursa.Demo/Views/MainWindow.axaml
+++ b/demo/Ursa.Demo/Views/MainWindow.axaml
@@ -35,6 +35,9 @@
+
+
+
diff --git a/src/Ursa.Themes.Semi/Controls/Loading.axaml b/src/Ursa.Themes.Semi/Controls/Loading.axaml
new file mode 100644
index 0000000..8cdf7f6
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Controls/Loading.axaml
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Ursa.Themes.Semi/Controls/_index.axaml b/src/Ursa.Themes.Semi/Controls/_index.axaml
index 8cf36e5..c0c304a 100644
--- a/src/Ursa.Themes.Semi/Controls/_index.axaml
+++ b/src/Ursa.Themes.Semi/Controls/_index.axaml
@@ -5,6 +5,7 @@
+
diff --git a/src/Ursa.Themes.Semi/Converters/BrushToColorConverter.cs b/src/Ursa.Themes.Semi/Converters/BrushToColorConverter.cs
new file mode 100644
index 0000000..e8074a2
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Converters/BrushToColorConverter.cs
@@ -0,0 +1,23 @@
+using System.Globalization;
+using Avalonia;
+using Avalonia.Data.Converters;
+using Avalonia.Media;
+
+namespace Ursa.Themes.Semi.Converters;
+
+public class BrushToColorConverter: IValueConverter
+{
+ public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ if (value is ISolidColorBrush b)
+ {
+ return b.Color;
+ }
+ return Colors.Transparent;
+ }
+
+ public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+}
\ No newline at end of file
diff --git a/src/Ursa.Themes.Semi/Themes/Dark/Loading.axaml b/src/Ursa.Themes.Semi/Themes/Dark/Loading.axaml
new file mode 100644
index 0000000..bcaa9b5
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Themes/Dark/Loading.axaml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/Ursa.Themes.Semi/Themes/Dark/_index.axaml b/src/Ursa.Themes.Semi/Themes/Dark/_index.axaml
index cc3a735..025d14f 100644
--- a/src/Ursa.Themes.Semi/Themes/Dark/_index.axaml
+++ b/src/Ursa.Themes.Semi/Themes/Dark/_index.axaml
@@ -5,6 +5,7 @@
+
diff --git a/src/Ursa.Themes.Semi/Themes/Light/Loading.axaml b/src/Ursa.Themes.Semi/Themes/Light/Loading.axaml
new file mode 100644
index 0000000..5680405
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Themes/Light/Loading.axaml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/Ursa.Themes.Semi/Themes/Light/_index.axaml b/src/Ursa.Themes.Semi/Themes/Light/_index.axaml
index cc3a735..025d14f 100644
--- a/src/Ursa.Themes.Semi/Themes/Light/_index.axaml
+++ b/src/Ursa.Themes.Semi/Themes/Light/_index.axaml
@@ -5,6 +5,7 @@
+
diff --git a/src/Ursa/Controls/Loading/Loading.cs b/src/Ursa/Controls/Loading/Loading.cs
new file mode 100644
index 0000000..a444dc2
--- /dev/null
+++ b/src/Ursa/Controls/Loading/Loading.cs
@@ -0,0 +1,26 @@
+using Avalonia;
+using Avalonia.Controls;
+
+namespace Ursa.Controls;
+
+public class Loading: ContentControl
+{
+ public static readonly StyledProperty