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
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License
// See the LICENSE file in the project root for more information.
// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone
Expand Down
2 changes: 1 addition & 1 deletion src/BootstrapBlazor/BootstrapBlazor.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<Version>10.5.1-beta02</Version>
<Version>10.5.1-beta05</Version>
</PropertyGroup>
Comment on lines 3 to 5
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR title/linked issue indicate a documentation-only change, but this PR also introduces behavioral changes (new AppendToBody option, JS logic changes) and bumps the package version. Please align the PR metadata/title/description with the actual scope, or split version bump/behavior changes into a separate PR.

Copilot uses AI. Check for mistakes.

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/BootstrapBlazor/Components/Mask/Mask.razor
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@namespace BootstrapBlazor.Components
@namespace BootstrapBlazor.Components
@inherits BootstrapModuleComponentBase
@attribute [BootstrapModuleAutoLoader(AutoInvokeInit = false, AutoInvokeDispose = false)]

Expand Down
35 changes: 30 additions & 5 deletions src/BootstrapBlazor/Components/Mask/Mask.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public partial class Mask
.Build();

private MaskOption? _options;
private bool _show = false;

/// <summary>
/// <inheritdoc/>
Expand All @@ -45,22 +46,46 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
{
await InvokeVoidAsync("update", Id, new
{
Show = _options != null,
Show = _show,
_options?.ContainerId,
_options?.Selector
_options?.Selector,
_options?.AppendToBody
});
}
}

private Task Show(MaskOption? option)
{
_options = option;
if (option == null)
{
// 服务关闭遮罩调用
_options?.ChildContent = null;
_show = false;
}
else
{
// 服务打开遮罩调用
_options = option;
_show = true;
}
StateHasChanged();
return Task.CompletedTask;
}

private Task CloseAsync()
private Task CloseAsync() => Show(null);

/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="disposing"></param>
/// <returns></returns>
protected override async ValueTask DisposeAsync(bool disposing)
{
return Show(null);
await base.DisposeAsync(disposing);

if (disposing)
{
MaskService.UnRegister(this);
}
}
}
31 changes: 15 additions & 16 deletions src/BootstrapBlazor/Components/Mask/Mask.razor.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,30 @@
export function update(id, options) {
export function update(id, options) {
const mask = document.getElementById(id);
if (mask) {
const { show } = options;
const { show, appendToBody } = options;
const el = document.querySelector(`[data-bb-mask="${id}"]`);
const container = getContainerBySelector(options);
if (container) {
const position = container.style.getPropertyValue('position');
if (position === '' || position === 'static') {
container.style.setProperty('position', 'relative');
}
if (show) {
el.style.setProperty('--bb-mask-position', 'absolute');
container.appendChild(el);
}
reset(el, mask, container, show);
}
else {
document.body.appendChild(el);
else if (appendToBody === true) {
reset(el, mask, document.body, show);
}
Comment on lines +14 to 16
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When appendToBody is false and no container is resolved, the mask element stays inside the <template> and therefore won’t be rendered/visible even when show is true. Consider appending to a sensible default (e.g., mask.parentElement) or enforcing that containerId/selector must be set when appendToBody is false (with a clear error).

Copilot uses AI. Check for mistakes.
}
}

if (show) {
el.classList.add('show');
}
else {
el.classList.remove('show');
el.style.removeProperty('--bb-mask-position');
mask.appendChild(el);
}
const reset = (el, mask, container, status) => {
if (status) {
container.appendChild(el);
el.classList.add('show');
}
else {
el.classList.remove('show');
mask.appendChild(el);
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/BootstrapBlazor/Components/Mask/Mask.razor.scss
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
@use "../../wwwroot/scss/variables" as *;
@use "../../wwwroot/scss/variables" as *;

.bb-mask {
--bb-mask-zindex: #{$bb-mask-zindex};
--bb-mask-bg: #{$bb-mask-bg};
--bb-mask-opacity: #{$bb-mask-opacity};
--bb-mask-position: fixed;
position: var(--bb-mask-position);
position: absolute;
top: 0;
right: 0;
bottom: 0;
Expand Down
7 changes: 7 additions & 0 deletions src/BootstrapBlazor/Components/Mask/MaskOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,11 @@ public class MaskOption
/// <para lang="en">Gets or sets Mask Parent Container Selector. Default null</para>
/// </summary>
public string? Selector { get; set; }

/// <summary>
/// <para lang="zh">获得/设置 是否将遮罩追加到 body 元素 默认 true</para>
/// <para lang="en">Gets or sets whether to append the mask to the body element. Default true</para>
/// <para>v<vesion>10.5.1</vesion></para>
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

XML doc tag appears misspelled: <vesion> isn’t used elsewhere in the codebase (convention is <version>). This will likely break doc tooling / consistency; please change to <version>.

Suggested change
/// <para>v<vesion>10.5.1</vesion></para>
/// <para>v<version>10.5.1</version></para>

Copilot uses AI. Check for mistakes.
/// </summary>
public bool AppendToBody { get; set; } = true;
Comment on lines +51 to +55
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (typo): Fix the <vesion> tag typo and redundant leading v in the XML doc.

The vesion tag appears to be a typo, and the leading v makes the XML odd. Use a proper tag (e.g. <version>10.5.1</version>) that your tooling recognizes so XML parsers and doc generators can handle it correctly.

Suggested change
/// <para lang="zh">获得/设置 是否将遮罩追加到 body 元素 默认 true</para>
/// <para lang="en">Gets or sets whether to append the mask to the body element. Default true</para>
/// <para>v<vesion>10.5.1</vesion></para>
/// </summary>
public bool AppendToBody { get; set; } = true;
/// <para lang="zh">获得/设置 是否将遮罩追加到 body 元素 默认 true</para>
/// <para lang="en">Gets or sets whether to append the mask to the body element. Default true</para>
/// <para><version>10.5.1</version></para>
/// </summary>
public bool AppendToBody { get; set; } = true;

}
82 changes: 43 additions & 39 deletions src/BootstrapBlazor/Extensions/MaskServiceExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,46 +11,50 @@ namespace BootstrapBlazor.Components;
/// </summary>
public static class MaskServiceExtensions
{

/// <summary>
/// <para lang="zh">Show 扩展方法</para>
/// <para lang="en">Show extension method</para>
/// </summary>
/// <param name="maskService"></param>
/// <param name="parameters"></param>
/// <param name="containerId"></param>
/// <param name="backgroundColor"></param>
/// <param name="opacity"></param>
/// <param name="zIndex"></param>
/// <param name="mask"></param>
public static Task Show<TComponent>(this MaskService maskService, IDictionary<string, object?>? parameters = null, string? containerId = null, string? backgroundColor = null, float opacity = 0.5f, int zIndex = 1050, Mask? mask = null) where TComponent : ComponentBase => maskService.Show(new MaskOption()
extension(MaskService maskService)
{
BackgroundColor = backgroundColor,
Opacity = opacity,
ZIndex = zIndex,
ContainerId = containerId,
ChildContent = BootstrapDynamicComponent.CreateComponent<TComponent>(parameters).Render()
}, mask);
/// <summary>
/// <para lang="zh">Show 扩展方法</para>
/// <para lang="en">Show extension method</para>
/// </summary>
/// <param name="parameters"></param>
/// <param name="containerId"></param>
/// <param name="backgroundColor"></param>
/// <param name="opacity"></param>
/// <param name="zIndex"></param>
/// <param name="appendToBody"></param>
/// <param name="mask"></param>
public Task Show<TComponent>(IDictionary<string, object?>? parameters = null, string? containerId = null, string? backgroundColor = null, float opacity = 0.5f, int zIndex = 1050, bool appendToBody = true, Mask? mask = null) where TComponent : ComponentBase => maskService.Show(new MaskOption()
{
BackgroundColor = backgroundColor,
Opacity = opacity,
ZIndex = zIndex,
ContainerId = containerId,
ChildContent = BootstrapDynamicComponent.CreateComponent<TComponent>(parameters).Render(),
AppendToBody = appendToBody
}, mask);


/// <summary>
/// <para lang="zh">Show 扩展方法</para>
/// <para lang="en">Show extension method</para>
/// </summary>
/// <param name="maskService"></param>
/// <param name="type"></param>
/// <param name="parameters"></param>
/// <param name="containerId"></param>
/// <param name="backgroundColor"></param>
/// <param name="opacity"></param>
/// <param name="zIndex"></param>
/// <param name="mask"></param>
public static Task Show(this MaskService maskService, Type type, IDictionary<string, object?>? parameters = null, string? containerId = null, string? backgroundColor = null, float opacity = 0.5f, int zIndex = 1050, Mask? mask = null) => maskService.Show(new MaskOption()
{
BackgroundColor = backgroundColor,
Opacity = opacity,
ZIndex = zIndex,
ContainerId = containerId,
ChildContent = BootstrapDynamicComponent.CreateComponent(type, parameters).Render()
}, mask);
/// <summary>
/// <para lang="zh">Show 扩展方法</para>
/// <para lang="en">Show extension method</para>
/// </summary>
/// <param name="type"></param>
/// <param name="parameters"></param>
/// <param name="containerId"></param>
/// <param name="backgroundColor"></param>
/// <param name="opacity"></param>
/// <param name="zIndex"></param>
/// <param name="appendToBody"></param>
/// <param name="mask"></param>
public Task Show(Type type, IDictionary<string, object?>? parameters = null, string? containerId = null, string? backgroundColor = null, float opacity = 0.5f, int zIndex = 1050, bool appendToBody = true, Mask? mask = null) => maskService.Show(new MaskOption()
{
BackgroundColor = backgroundColor,
Opacity = opacity,
ZIndex = zIndex,
ContainerId = containerId,
ChildContent = BootstrapDynamicComponent.CreateComponent(type, parameters).Render(),
AppendToBody = appendToBody
}, mask);
}
}
23 changes: 22 additions & 1 deletion test/UnitTest/Services/MaskServiceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ await maskService.Show(new MaskOption()
BackgroundColor = "#000",
Opacity = 0.5f,
ZIndex = 1050,
ChildContent = builder => builder.AddContent(0, "test-mask-content")
ChildContent = builder => builder.AddContent(0, "test-mask-content"),
AppendToBody = true
});
});
});
Expand Down Expand Up @@ -116,6 +117,26 @@ public async Task Show_Type()
await cut.InvokeAsync(() => button.Click());
}

[Fact]
public async Task Show_Ok()
{
var maskService = Context.Services.GetRequiredService<MaskService>();
var cut = Context.Render<BootstrapBlazorRoot>(pb =>
{
pb.AddChildContent<Button>(pb =>
{
pb.Add(a => a.OnClickWithoutRender, async () =>
{
await maskService.Show((MaskOption)null!);
});
});
});
var button = cut.Find("button");
await cut.InvokeAsync(() => button.Click());

// 遮罩参数 MaskOption 强制为 null 不报错
}

class MockComponent : ComponentBase
{
[CascadingParameter]
Expand Down
Loading