diff --git a/src/ShadUI.Demo/MainWindow.axaml b/src/ShadUI.Demo/MainWindow.axaml
index 3caba83..86ef097 100644
--- a/src/ShadUI.Demo/MainWindow.axaml
+++ b/src/ShadUI.Demo/MainWindow.axaml
@@ -275,6 +275,20 @@
+
+
+
+
+
+
+
]
[Transient]
[Transient]
+[Transient]
[Transient]
[Transient]
[Transient]
diff --git a/src/ShadUI.Demo/ShadUI.Demo.csproj b/src/ShadUI.Demo/ShadUI.Demo.csproj
index 74f5dab..0753bf4 100644
--- a/src/ShadUI.Demo/ShadUI.Demo.csproj
+++ b/src/ShadUI.Demo/ShadUI.Demo.csproj
@@ -45,14 +45,20 @@
+
+
+ PoupMaskPage.axaml
+
+
+
-
+
@@ -60,8 +66,8 @@
-
+
diff --git a/src/ShadUI.Demo/ViewModels/PoupMaskViewModel.cs b/src/ShadUI.Demo/ViewModels/PoupMaskViewModel.cs
new file mode 100644
index 0000000..b30de1a
--- /dev/null
+++ b/src/ShadUI.Demo/ViewModels/PoupMaskViewModel.cs
@@ -0,0 +1,128 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ShadUI.Demo.ViewModels
+{
+ [Page("poupmask")]
+ public sealed partial class PoupMaskViewModel : ViewModelBase, INavigable
+ {
+ private readonly PageManager _pageManager;
+
+ private readonly ToastManager _toastManager;
+ private readonly LoginViewModel _loginViewModel;
+
+ public PoupMaskViewModel(
+ PageManager pageManager,
+ ToastManager toastManager,
+ LoginViewModel loginViewModel)
+ {
+ _pageManager = pageManager;
+ _userControlManager = new DialogManager();
+ _toastManager = toastManager;
+ _loginViewModel = loginViewModel;
+
+ var path = Path.Combine(AppContext.BaseDirectory, "viewModels", "DialogViewModel.cs");
+ AlertDialogCode = WrapCode(path.ExtractByLineRange(62, 78).CleanIndentation());
+ DestructiveAlertDialogCode = WrapCode(path.ExtractByLineRange(83, 100).CleanIndentation());
+ CustomDialogCode = WrapCode(path.ExtractByLineRange(105, 122).CleanIndentation());
+ }
+
+ [RelayCommand]
+ private void BackPage()
+ {
+ _pageManager.Navigate();
+ }
+
+ [RelayCommand]
+ private void NextPage()
+ {
+ _pageManager.Navigate();
+ }
+
+ private string WrapCode(string code)
+ {
+ return $"""
+ using CommunityToolkit.Mvvm.Input;
+
+ //..other code
+
+ {code}
+
+ //..rest of the code
+
+ """;
+ }
+
+ [ObservableProperty]
+ private string _alertDialogCode = string.Empty;
+ [ObservableProperty]
+ private DialogManager _userControlManager;
+
+ [RelayCommand]
+ private void ShowDialog()
+ {
+ _userControlManager
+ .CreateDialog(
+ "Are you absolutely sure?",
+ "This action cannot be undone. This will permanently delete your account and remove your data from our servers.")
+ .WithPrimaryButton("Continue",
+ () => _toastManager.CreateToast("Delete account")
+ .WithContent("Account deleted successfully!")
+ .DismissOnClick()
+ .ShowSuccess())
+ .WithCancelButton("Cancel")
+ .WithMaxWidth(512)
+ .Dismissible().Show();
+ }
+
+ [ObservableProperty]
+ private string _destructiveAlertDialogCode = string.Empty;
+
+ [RelayCommand]
+ private void ShowDestructiveStyleDialog()
+ {
+ _userControlManager
+ .CreateDialog(
+ "Are you absolutely sure?",
+ "This action cannot be undone. This will permanently delete your account and remove your data from our servers.")
+ .WithPrimaryButton("Continue",
+ () => _toastManager.CreateToast("Delete account")
+ .WithContent("Account deleted successfully!")
+ .DismissOnClick()
+ .ShowSuccess()
+ , DialogButtonStyle.Destructive)
+ .WithCancelButton("Cancel")
+ .WithMaxWidth(512)
+ .Dismissible()
+ .Show();
+ }
+
+ [ObservableProperty]
+ private string _customDialogCode = string.Empty;
+
+ [RelayCommand]
+ private void ShowCustomDialog()
+ {
+ _loginViewModel.Initialize();
+ _userControlManager.CreateDialog(_loginViewModel)
+ .Dismissible()
+ .WithSuccessCallback(vm =>
+ _toastManager.CreateToast("Sign in successful")
+ .WithContent($"Hi {vm.Email}, welcome back!")
+ .DismissOnClick()
+ .ShowSuccess())
+ .WithCancelCallback(() =>
+ _toastManager.CreateToast("Sign in cancelled")
+ .WithContent("Please sign in to continue.")
+ .DismissOnClick()
+ .ShowWarning())
+ .Show();
+ }
+ }
+}
diff --git a/src/ShadUI.Demo/Views/PoupMaskPage.axaml b/src/ShadUI.Demo/Views/PoupMaskPage.axaml
new file mode 100644
index 0000000..fb968a6
--- /dev/null
+++ b/src/ShadUI.Demo/Views/PoupMaskPage.axaml
@@ -0,0 +1,172 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ShadUI.Demo/Views/PoupMaskPage.axaml.cs b/src/ShadUI.Demo/Views/PoupMaskPage.axaml.cs
new file mode 100644
index 0000000..8ec136f
--- /dev/null
+++ b/src/ShadUI.Demo/Views/PoupMaskPage.axaml.cs
@@ -0,0 +1,13 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace ShadUI.Demo.Views;
+
+public partial class PoupMaskPage : UserControl
+{
+ public PoupMaskPage()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/src/ShadUI/AttachedProperties/ListBoxItemAssist.cs b/src/ShadUI/AttachedProperties/ListBoxItemAssist.cs
new file mode 100644
index 0000000..715cff9
--- /dev/null
+++ b/src/ShadUI/AttachedProperties/ListBoxItemAssist.cs
@@ -0,0 +1,35 @@
+using Avalonia;
+using Avalonia.Controls;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ShadUI
+{
+ ///
+ /// ListBoxItemAssist
+ ///
+ public static class ListBoxItemAssist
+ {
+ ///
+ /// Gets or sets control display check icon.
+ ///
+ public static readonly AttachedProperty ShowCheckIconProperty =
+ AvaloniaProperty.RegisterAttached(
+ "ShowCheckIcon", typeof(ListBoxItemAssist),true);
+ ///
+ /// Gets the value of
+ ///
+ ///
+ ///
+ public static void SetShowCheckIcon(AvaloniaObject element, bool value) =>
+ element.SetValue(ShowCheckIconProperty, value);
+ ///
+ /// Gets the value of
+ ///
+ ///
+ ///
+ public static bool GetShowCheckIcon(AvaloniaObject element) =>
+ element.GetValue(ShowCheckIconProperty);
+ }
+}
diff --git a/src/ShadUI/Controls/Dialog/DialogHost.axaml.cs b/src/ShadUI/Controls/Dialog/DialogHost.axaml.cs
index ef0070f..cc55a12 100644
--- a/src/ShadUI/Controls/Dialog/DialogHost.axaml.cs
+++ b/src/ShadUI/Controls/Dialog/DialogHost.axaml.cs
@@ -260,7 +260,7 @@ private void DetachManagerEvents(DialogManager manager)
private void ManagerOnDialogShown(object sender, DialogShownEventArgs e)
{
- if (Manager is null || Owner is null) return;
+ if (Manager is null) return;
Dialog = e.Control;
Dismissible = e.Options.Dismissible;
@@ -270,21 +270,23 @@ private void ManagerOnDialogShown(object sender, DialogShownEventArgs e)
IsDialogOpen = true;
HasOpenDialog = true;
- Owner.HasOpenDialog = true;
+ if (Owner is { })
+ Owner.HasOpenDialog = true;
}
private async void ManagerOnDialogClosed(object sender, DialogClosedEventArgs e)
{
try
{
- if (Manager is null || Owner is null) return;
+ if (Manager is null) return;
if (e.Control != Dialog) return;
IsDialogOpen = false;
if (e.ReplaceExisting) return;
HasOpenDialog = Manager.Dialogs.Count > 0;
- Owner.HasOpenDialog = Manager.Dialogs.Count > 0;
+ if (Owner is { })
+ Owner.HasOpenDialog = Manager.Dialogs.Count > 0;
await Task.Delay(200); // Allow animations to complete
if (!HasOpenDialog) Dialog = null;
diff --git a/src/ShadUI/Controls/ListBox/ListBoxItem.axaml b/src/ShadUI/Controls/ListBox/ListBoxItem.axaml
index 602f6ea..5a79744 100644
--- a/src/ShadUI/Controls/ListBox/ListBoxItem.axaml
+++ b/src/ShadUI/Controls/ListBox/ListBoxItem.axaml
@@ -8,9 +8,9 @@
Width="200"
Height="300"
Margin="24">
- Item 1
+ Item 1
Item 2
- Item 3
+ Item 3
Item 4
Item 5
Item 6
@@ -80,6 +80,7 @@
DockPanel.Dock="Right"
Foreground="{DynamicResource ForegroundColor}" />
+
diff --git a/src/ShadUI/Controls/Popup/PopupMask.axaml.cs b/src/ShadUI/Controls/Popup/PopupMask.axaml.cs
new file mode 100644
index 0000000..9d669ac
--- /dev/null
+++ b/src/ShadUI/Controls/Popup/PopupMask.axaml.cs
@@ -0,0 +1,56 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.Primitives;
+using Avalonia.Media;
+using Avalonia.Reactive;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ShadUI
+{
+ ///
+ ///
+ ///
+ public class PopupMask : TemplatedControl
+ {
+ /// These controls are displayed above all others and fill the entire window.
+ /// Useful for things like popups.
+ ///
+ public static readonly StyledProperty HostsProperty =
+ AvaloniaProperty.Register(nameof(Hosts), []);
+
+ ///
+ /// These controls are displayed above all others and fill the entire window.
+ ///
+ public Controls Hosts
+ {
+ get => GetValue(HostsProperty);
+ set => SetValue(HostsProperty, value);
+ }
+ ///
+ ///
+ ///
+ ///
+ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
+ {
+ base.OnApplyTemplate(e);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
+ {
+ base.OnDetachedFromVisualTree(e);
+ }
+ ///
+ ///
+ ///
+ public PopupMask()
+ {
+ Hosts = [];
+ }
+ }
+}
diff --git a/src/ShadUI/Controls/Styles.axaml b/src/ShadUI/Controls/Styles.axaml
index 8640ac8..0a46f39 100644
--- a/src/ShadUI/Controls/Styles.axaml
+++ b/src/ShadUI/Controls/Styles.axaml
@@ -7,4 +7,5 @@
+
\ No newline at end of file