feat(ui): add reusable ModalShell control

This commit is contained in:
mika kuns
2026-05-30 16:38:02 +02:00
parent 16b0d1177a
commit c20fbe3613
3 changed files with 82 additions and 0 deletions
@@ -0,0 +1,38 @@
using System;
using System.Windows.Input;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
namespace ClaudeDo.Ui.Views.Controls;
/// <summary>Reusable modal chrome: titlebar (drag + close) wrapping a body and optional footer.</summary>
public class ModalShell : ContentControl
{
public static readonly StyledProperty<string?> TitleProperty =
AvaloniaProperty.Register<ModalShell, string?>(nameof(Title));
public static readonly StyledProperty<object?> FooterProperty =
AvaloniaProperty.Register<ModalShell, object?>(nameof(Footer));
public static readonly StyledProperty<ICommand?> CloseCommandProperty =
AvaloniaProperty.Register<ModalShell, ICommand?>(nameof(CloseCommand));
public string? Title { get => GetValue(TitleProperty); set => SetValue(TitleProperty, value); }
public object? Footer { get => GetValue(FooterProperty); set => SetValue(FooterProperty, value); }
public ICommand? CloseCommand { get => GetValue(CloseCommandProperty); set => SetValue(CloseCommandProperty, value); }
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
if (e.NameScope.Find<Border>("PART_TitleBar") is { } bar)
bar.PointerPressed += OnTitleBarPressed;
}
private void OnTitleBarPressed(object? sender, PointerPressedEventArgs e)
{
if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed && VisualRoot is Window w)
w.BeginMoveDrag(e);
}
}