diff --git a/demo/Ursa.Demo/App.axaml b/demo/Ursa.Demo/App.axaml
index 004d33b..218b0f4 100644
--- a/demo/Ursa.Demo/App.axaml
+++ b/demo/Ursa.Demo/App.axaml
@@ -5,5 +5,6 @@
xmlns:local="using:Ursa.Demo">
+
diff --git a/demo/Ursa.Demo/App.axaml.cs b/demo/Ursa.Demo/App.axaml.cs
index 990010b..47a67b5 100644
--- a/demo/Ursa.Demo/App.axaml.cs
+++ b/demo/Ursa.Demo/App.axaml.cs
@@ -21,7 +21,6 @@ public partial class App : Application
{
// Line below is needed to remove Avalonia data validation.
// Without this line you will get duplicate validations from both Avalonia and CT
- ExpressionObserver.DataValidators.RemoveAll(x => x is DataAnnotationsValidationPlugin);
desktop.MainWindow = new MainWindow
{
DataContext = new MainWindowViewModel(),
diff --git a/demo/Ursa.Demo/Ursa.Demo.csproj b/demo/Ursa.Demo/Ursa.Demo.csproj
index 81079f9..039cf87 100644
--- a/demo/Ursa.Demo/Ursa.Demo.csproj
+++ b/demo/Ursa.Demo/Ursa.Demo.csproj
@@ -18,12 +18,17 @@
-
-
+
+
-
+
-
+
+
+
+
+
+
diff --git a/demo/Ursa.Demo/ViewLocator.cs b/demo/Ursa.Demo/ViewLocator.cs
deleted file mode 100644
index 2a2e3cf..0000000
--- a/demo/Ursa.Demo/ViewLocator.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System;
-using Avalonia.Controls;
-using Avalonia.Controls.Templates;
-using Ursa.Demo.ViewModels;
-
-namespace Ursa.Demo;
-
-public class ViewLocator : IDataTemplate
-{
- public IControl Build(object data)
- {
- var name = data.GetType().FullName!.Replace("ViewModel", "View");
- var type = Type.GetType(name);
-
- if (type != null)
- {
- return (Control)Activator.CreateInstance(type)!;
- }
-
- return new TextBlock { Text = "Not Found: " + name };
- }
-
- public bool Match(object data)
- {
- return data is ViewModelBase;
- }
-}
\ No newline at end of file
diff --git a/src/Ursa.Themes.Semi/Controls/Banner.axaml b/src/Ursa.Themes.Semi/Controls/Banner.axaml
new file mode 100644
index 0000000..b3b2954
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Controls/Banner.axaml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Ursa.Themes.Semi/Controls/_index.axaml b/src/Ursa.Themes.Semi/Controls/_index.axaml
new file mode 100644
index 0000000..8827a5d
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Controls/_index.axaml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/src/Ursa.Themes.Semi/Index.axaml b/src/Ursa.Themes.Semi/Index.axaml
new file mode 100644
index 0000000..5c182e5
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Index.axaml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Ursa.Themes.Semi/Themes/Dark/Banner.axaml b/src/Ursa.Themes.Semi/Themes/Dark/Banner.axaml
new file mode 100644
index 0000000..9017e8d
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Themes/Dark/Banner.axaml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/Ursa.Themes.Semi/Themes/Dark/_index.axaml b/src/Ursa.Themes.Semi/Themes/Dark/_index.axaml
new file mode 100644
index 0000000..8827a5d
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Themes/Dark/_index.axaml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/src/Ursa.Themes.Semi/Themes/Light/Banner.axaml b/src/Ursa.Themes.Semi/Themes/Light/Banner.axaml
new file mode 100644
index 0000000..9017e8d
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Themes/Light/Banner.axaml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/Ursa.Themes.Semi/Themes/Light/_index.axaml b/src/Ursa.Themes.Semi/Themes/Light/_index.axaml
new file mode 100644
index 0000000..8827a5d
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Themes/Light/_index.axaml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/src/Ursa.Themes.Semi/Themes/Shared/Banner.axaml b/src/Ursa.Themes.Semi/Themes/Shared/Banner.axaml
new file mode 100644
index 0000000..9017e8d
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Themes/Shared/Banner.axaml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/Ursa.Themes.Semi/Themes/Shared/_index.axaml b/src/Ursa.Themes.Semi/Themes/Shared/_index.axaml
new file mode 100644
index 0000000..8827a5d
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Themes/Shared/_index.axaml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/src/Ursa.Themes.Semi/Ursa.Themes.Semi.csproj b/src/Ursa.Themes.Semi/Ursa.Themes.Semi.csproj
index 0e8b4fd..7fb04b2 100644
--- a/src/Ursa.Themes.Semi/Ursa.Themes.Semi.csproj
+++ b/src/Ursa.Themes.Semi/Ursa.Themes.Semi.csproj
@@ -1,22 +1,19 @@
- net7.0
+ netstandard2.0
enable
enable
+ 11
-
+
-
-
-
-
-
+
diff --git a/src/Ursa/AssemblyInfo.cs b/src/Ursa/AssemblyInfo.cs
new file mode 100644
index 0000000..9ead9aa
--- /dev/null
+++ b/src/Ursa/AssemblyInfo.cs
@@ -0,0 +1,4 @@
+using Avalonia.Metadata;
+
+[assembly:XmlnsDefinition("https://irihi.tech/ursa", "Ursa")]
+[assembly:XmlnsDefinition("https://irihi.tech/ursa", "Ursa.Controls")]
\ No newline at end of file
diff --git a/src/Ursa/Controls/Banner.cs b/src/Ursa/Controls/Banner.cs
new file mode 100644
index 0000000..dc24614
--- /dev/null
+++ b/src/Ursa/Controls/Banner.cs
@@ -0,0 +1,44 @@
+using Avalonia;
+using Avalonia.Controls;
+
+namespace Ursa.Controls;
+
+public enum BannerType
+{
+ None,
+ Info,
+ Warning,
+ Danger,
+ Success,
+}
+public class Banner: ContentControl
+{
+ public static readonly StyledProperty CanCloseProperty = AvaloniaProperty.Register(
+ nameof(CanClose));
+
+ public bool CanClose
+ {
+ get => GetValue(CanCloseProperty);
+ set => SetValue(CanCloseProperty, value);
+ }
+
+ public static readonly StyledProperty ShowIconProperty = AvaloniaProperty.Register(
+ nameof(ShowIcon));
+
+ public bool ShowIcon
+ {
+ get => GetValue(ShowIconProperty);
+ set => SetValue(ShowIconProperty, value);
+ }
+
+ public static readonly StyledProperty