Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/CommunityToolkit.Maui.UnitTests/BaseViewTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ static void InitializeServicesAndSetMockApplication(out IServiceProvider service
appBuilder.Services.AddTransientPopup<ShortLivedSelfClosingPopup, ShortLivedMockPageViewModel>();
appBuilder.Services.AddTransientPopup<GarbageCollectionHeavySelfClosingPopup, MockPageViewModel>();
appBuilder.Services.AddTransientPopup<SingleConstructionPopup, SingleConstructionViewModel>();

appBuilder.Services.AddTransientPopup<CustomButton>();

appBuilder.Services.AddTransientPopup<MockPopup>();
#endregion

Expand All @@ -82,4 +83,6 @@ static void InitializeServicesAndSetMockApplication(out IServiceProvider service

CreateViewHandler<MockPageHandler>(shell);
}

protected sealed class CustomButton : Button;
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#pragma warning disable CA1416
using CommunityToolkit.Maui.UnitTests.Services;
using CommunityToolkit.Maui.Views;
using Xunit;

namespace CommunityToolkit.Maui.UnitTests.Views;

#pragma warning disable CA1416
public class DefaultPopupSettingsTests : BaseTest
public class DefaultPopupSettingsTests : BaseViewTest
{
[Fact]
public void Popup_SetPopupDefaultsNotCalled_UsesPopupDefaults()
Expand Down Expand Up @@ -97,5 +98,103 @@ public void View_SetPopupDefaultsCalled_UsesDefaultPopupSettings()
Assert.Equal(defaultPopupSettings.VerticalOptions, popupBorder.VerticalOptions);
Assert.Equal(defaultPopupSettings.HorizontalOptions, popupBorder.HorizontalOptions);
}

[Fact(Timeout = (int)TestDuration.Medium)]
public void PopupService_View_SetPopupDefaultsCalled_UsesDefaultPopupSettings()
{
// Arrange
var defaultPopupSettings = new DefaultPopupSettings
{
CanBeDismissedByTappingOutsideOfPopup = false,
BackgroundColor = Colors.Orange,
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.Start,
Margin = 72,
Padding = 4
};

if (Application.Current?.Windows[0].Page is not Page page)
{
throw new InvalidOperationException("Page cannot be null");
}

var builder = MauiApp.CreateBuilder();
builder.UseMauiCommunityToolkit(options => { options.SetPopupDefaults(defaultPopupSettings); });

// Act
var popupService = ServiceProvider.GetRequiredService<IPopupService>();
popupService.ShowPopup<CustomButton>(page.Navigation);

if (Application.Current.Windows[0].Page is not Shell { CurrentPage: PopupPage popupPage })
{
Assert.Fail("Popup page not found");
throw new InvalidOperationException("Popup page not found");
}

var popupBorder = popupPage.Content.PopupBorder;
var popup = (Popup)(popupBorder.Content ?? throw new InvalidOperationException("PopupBorder Content cannot be null"));
var underlyingContentView = (ContentView)popup;

// Assert
Assert.Equal(defaultPopupSettings.BackgroundColor, popup.BackgroundColor);
Assert.Equal(defaultPopupSettings.CanBeDismissedByTappingOutsideOfPopup, popup.CanBeDismissedByTappingOutsideOfPopup);
Assert.Equal(defaultPopupSettings.Margin, popupBorder.Margin);
Assert.Equal(defaultPopupSettings.VerticalOptions, popupBorder.VerticalOptions);
Assert.Equal(defaultPopupSettings.HorizontalOptions, popupBorder.HorizontalOptions);
Assert.Equal(defaultPopupSettings.Padding, popup.Padding);
Assert.Equal(defaultPopupSettings.Padding, underlyingContentView.Padding);
Assert.Equal(Thickness.Zero, underlyingContentView.Margin);
Assert.Equal(LayoutOptions.Fill, underlyingContentView.HorizontalOptions);
Assert.Equal(LayoutOptions.Fill, underlyingContentView.VerticalOptions);
}

[Fact(Timeout = (int)TestDuration.Medium)]
public void PopupService_Popup_SetPopupDefaultsCalled_UsesDefaultPopupSettings()
{
// Arrange
var defaultPopupSettings = new DefaultPopupSettings
{
CanBeDismissedByTappingOutsideOfPopup = true,
BackgroundColor = Colors.Orange,
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.Start,
Margin = 72,
Padding = 4
};

if (Application.Current?.Windows[0].Page is not Page page)
{
throw new InvalidOperationException("Page cannot be null");
}

var builder = MauiApp.CreateBuilder();
builder.UseMauiCommunityToolkit(options => { options.SetPopupDefaults(defaultPopupSettings); });

// Act
var popupService = ServiceProvider.GetRequiredService<IPopupService>();
popupService.ShowPopup<MockPopup>(page.Navigation);

if (Application.Current.Windows[0].Page is not Shell { CurrentPage: PopupPage popupPage })
{
Assert.Fail("Popup page not found");
throw new InvalidOperationException("Popup page not found");
}

var popupBorder = popupPage.Content.PopupBorder;
var popup = (Popup)(popupBorder.Content ?? throw new InvalidOperationException("PopupBorder Content cannot be null"));
var underlyingContentView = (ContentView)popup;

// Assert
Assert.Equal(defaultPopupSettings.BackgroundColor, popup.BackgroundColor);
Assert.Equal(defaultPopupSettings.CanBeDismissedByTappingOutsideOfPopup, popup.CanBeDismissedByTappingOutsideOfPopup);
Assert.Equal(defaultPopupSettings.Margin, popupBorder.Margin);
Assert.Equal(defaultPopupSettings.VerticalOptions, popupBorder.VerticalOptions);
Assert.Equal(defaultPopupSettings.HorizontalOptions, popupBorder.HorizontalOptions);
Assert.Equal(defaultPopupSettings.Padding, popup.Padding);
Assert.Equal(defaultPopupSettings.Padding, underlyingContentView.Padding);
Assert.Equal(Thickness.Zero, underlyingContentView.Margin);
Assert.Equal(LayoutOptions.Fill, underlyingContentView.HorizontalOptions);
Assert.Equal(LayoutOptions.Fill, underlyingContentView.VerticalOptions);
}
}
#pragma warning restore CA1416
24 changes: 14 additions & 10 deletions src/CommunityToolkit.Maui/Views/Popup/Popup.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public Popup()
HorizontalOptions = Options.DefaultPopupSettings.HorizontalOptions;
VerticalOptions = Options.DefaultPopupSettings.VerticalOptions;
BackgroundColor = Options.DefaultPopupSettings.BackgroundColor;
CanBeDismissedByTappingOutsideOfPopup = Options.DefaultPopupSettings.CanBeDismissedByTappingOutsideOfPopup;
}

/// <summary>
Expand All @@ -34,33 +35,36 @@ public Popup()
/// Gets or sets the margin between the <see cref="Popup"/> and the edge of the window.
/// </summary>
[BindableProperty]
public new partial Thickness Margin { get; set; } = Options.DefaultPopupSettings.Margin;

/// <summary>
/// Gets or sets the padding between the <see cref="Popup"/> border and the <see cref="Popup"/> content.
/// </summary>
[BindableProperty]
public new partial Thickness Padding { get; set; } = Options.DefaultPopupSettings.Padding;
public new partial Thickness Margin { get; set; }

/// <summary>
/// Gets or sets the horizontal position of the <see cref="Popup"/> when displayed on screen.
/// </summary>
[BindableProperty]
public new partial LayoutOptions HorizontalOptions { get; set; } = Options.DefaultPopupSettings.HorizontalOptions;
public new partial LayoutOptions HorizontalOptions { get; set; }

/// <summary>
/// Gets or sets the vertical position of the <see cref="Popup"/> when displayed on screen.
/// </summary>
[BindableProperty]
public new partial LayoutOptions VerticalOptions { get; set; } = Options.DefaultPopupSettings.VerticalOptions;
public new partial LayoutOptions VerticalOptions { get; set; }

/// <inheritdoc cref="IPopupOptions.CanBeDismissedByTappingOutsideOfPopup"/> />
/// <remarks>
/// When true and the user taps outside the popup, it will dismiss.
/// On Android - when false the hardware back button is disabled.
/// </remarks>
[BindableProperty]
public partial bool CanBeDismissedByTappingOutsideOfPopup { get; set; } = Options.DefaultPopupSettings.CanBeDismissedByTappingOutsideOfPopup;
public partial bool CanBeDismissedByTappingOutsideOfPopup { get; set; }

/// <summary>
/// Gets or sets the padding between the <see cref="Popup"/> border and the <see cref="Popup"/> content.
/// </summary>
public new Thickness Padding
{
get => base.Padding;
set => base.Padding = value;
}

/// <summary>
/// Close the Popup.
Expand Down
10 changes: 5 additions & 5 deletions src/CommunityToolkit.Maui/Views/Popup/PopupPage.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -282,35 +282,35 @@ sealed partial class HorizontalOptionsConverter : BaseConverterOneWay<LayoutOpti
{
public override LayoutOptions DefaultConvertReturnValue { get; set; } = Options.DefaultPopupSettings.HorizontalOptions;

public override LayoutOptions ConvertFrom(LayoutOptions value, CultureInfo? culture) => value == LayoutOptions.Fill ? Options.DefaultPopupSettings.HorizontalOptions : value;
public override LayoutOptions ConvertFrom(LayoutOptions value, CultureInfo? culture) => value == LayoutOptions.Fill ? DefaultConvertReturnValue : value;
}

sealed partial class VerticalOptionsConverter : BaseConverterOneWay<LayoutOptions, LayoutOptions>
{
public override LayoutOptions DefaultConvertReturnValue { get; set; } = Options.DefaultPopupSettings.VerticalOptions;

public override LayoutOptions ConvertFrom(LayoutOptions value, CultureInfo? culture) => value == LayoutOptions.Fill ? Options.DefaultPopupSettings.VerticalOptions : value;
public override LayoutOptions ConvertFrom(LayoutOptions value, CultureInfo? culture) => value == LayoutOptions.Fill ? DefaultConvertReturnValue : value;
}

sealed partial class BackgroundColorConverter : BaseConverterOneWay<Color?, Color>
{
public override Color DefaultConvertReturnValue { get; set; } = Options.DefaultPopupSettings.BackgroundColor;

public override Color ConvertFrom(Color? value, CultureInfo? culture) => value ?? Options.DefaultPopupSettings.BackgroundColor;
public override Color ConvertFrom(Color? value, CultureInfo? culture) => value ?? DefaultConvertReturnValue;
}
}

sealed partial class PaddingConverter : BaseConverterOneWay<Thickness, Thickness>
{
public override Thickness DefaultConvertReturnValue { get; set; } = Options.DefaultPopupSettings.Padding;

public override Thickness ConvertFrom(Thickness value, CultureInfo? culture) => value == default ? Options.DefaultPopupSettings.Padding : value;
public override Thickness ConvertFrom(Thickness value, CultureInfo? culture) => value.IsEmpty || value.IsNaN ? DefaultConvertReturnValue : value;
}

sealed partial class MarginConverter : BaseConverterOneWay<Thickness, Thickness>
{
public override Thickness DefaultConvertReturnValue { get; set; } = Options.DefaultPopupSettings.Margin;

public override Thickness ConvertFrom(Thickness value, CultureInfo? culture) => value == default ? Options.DefaultPopupSettings.Margin : value;
public override Thickness ConvertFrom(Thickness value, CultureInfo? culture) => value.IsEmpty || value.IsNaN ? DefaultConvertReturnValue : value;
}
}
Loading