From d8f35396283260edb620890fb148f54b6a605671 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Wed, 5 Mar 2025 09:28:04 +0800 Subject: [PATCH 1/7] =?UTF-8?q?doc:=20=E6=96=87=E6=A1=A3=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=B8=BA=E8=8B=B1=E8=AF=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Dialog/DialogOption.cs | 82 +++++++++---------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/src/BootstrapBlazor/Components/Dialog/DialogOption.cs b/src/BootstrapBlazor/Components/Dialog/DialogOption.cs index 13b9674d680..07c20b9fbe3 100644 --- a/src/BootstrapBlazor/Components/Dialog/DialogOption.cs +++ b/src/BootstrapBlazor/Components/Dialog/DialogOption.cs @@ -6,194 +6,194 @@ namespace BootstrapBlazor.Components; /// -/// Dialog 组件配置类 +/// Configuration class for the Dialog component /// public class DialogOption { /// - /// 获得/设置 相关弹窗实例 + /// Gets or sets the related modal instance /// internal Modal? Modal { get; set; } /// - /// 获得/设置 弹窗标题 + /// Gets or sets the dialog title /// public string? Title { get; set; } /// - /// 获得/设置 弹窗自定义样式 + /// Gets or sets the custom style of the dialog /// public string? Class { get; set; } /// - /// 获得/设置 弹窗大小 + /// Gets or sets the size of the dialog /// public Size Size { get; set; } = Size.ExtraExtraLarge; /// - /// 获得/设置 全屏弹窗 默认 None + /// Gets or sets the full screen size of the dialog, default is None /// - /// 为保证功能正常,设置值后 均不可用 + /// To ensure functionality, when this value is set, , , and are not available public FullScreenSize FullScreenSize { get; set; } = FullScreenSize.None; /// - /// 获得/设置 是否显示最大化按钮 默认 false 不显示 + /// Gets or sets whether to show the maximize button, default is false /// - /// 为保证功能正常,设置值为 true 后 均不可用 + /// To ensure functionality, when this value is set to true, and are not available public bool ShowMaximizeButton { get; set; } /// - /// 获得/设置 是否垂直居中 默认为 true + /// Gets or sets whether the dialog is vertically centered, default is true /// public bool IsCentered { get; set; } = true; /// - /// 获得/设置 是否弹窗正文超长时滚动 默认为 false + /// Gets or sets whether the dialog content scrolls when it is too long, default is false /// public bool IsScrolling { get; set; } = false; /// - /// 获得/设置 是否显示调整大小按钮 默认为 false + /// Gets or sets whether to show the resize button, default is false /// public bool ShowResize { get; set; } /// - /// 获得/设置 是否显示关闭按钮 默认为 true + /// Gets or sets whether to show the close button, default is true /// public bool ShowCloseButton { get; set; } = true; /// - /// 获得/设置 是否显示 Header 关闭按钮 默认为 true + /// Gets or sets whether to show the header close button, default is true /// public bool ShowHeaderCloseButton { get; set; } = true; /// - /// 获得/设置 是否支持键盘 ESC 关闭当前弹窗 默认 true 支持 + /// Gets or sets whether to support closing the dialog with the ESC key, default is true /// public bool IsKeyboard { get; set; } = true; /// - /// 获得/设置 是否支持点击遮罩关闭弹窗 默认 false + /// Gets or sets whether to support closing the dialog by clicking the backdrop, default is false /// public bool IsBackdrop { get; set; } /// - /// 获得/设置 是否显示 Footer 默认为 true + /// Gets or sets whether to show the footer, default is true /// public bool ShowFooter { get; set; } = true; /// - /// 获得/设置 是否显示打印按钮 默认 false 不显示 + /// Gets or sets whether to show the print button, default is false /// public bool ShowPrintButton { get; set; } /// - /// 获得/设置 是否显示保存按钮 默认 false 不显示 + /// Gets or sets whether to show the save button, default is false /// public bool ShowSaveButton { get; set; } /// - /// 获得/设置 打印按钮是否显示在 Header 中 默认 false 不显示 + /// Gets or sets whether to show the print button in the header, default is false /// public bool ShowPrintButtonInHeader { get; set; } /// - /// 获得/设置 Header 中打印按钮显示文字 默认为资源文件中 打印 + /// Gets or sets the text of the print button in the header, default is "Print" from the resource file /// public string? PrintButtonText { get; set; } /// - /// 获得/设置 相关连数据,多用于传值使用 + /// Gets or sets the related data, mostly used for passing values /// public object? BodyContext { get; set; } /// - /// 获得/设置 ModalBody 组件 + /// Gets or sets the ModalBody component /// public RenderFragment? BodyTemplate { get; set; } /// - /// 获得/设置 ModalFooter 组件 + /// Gets or sets the ModalFooter component /// public RenderFragment? FooterTemplate { get; set; } /// - /// 获得/设置 ModalHeader 组件模板 + /// Gets or sets the ModalHeader component template /// public RenderFragment? HeaderTemplate { get; set; } /// - /// 获得/设置 ModalHeader 组件自定义按钮 + /// Gets or sets the custom buttons in the ModalHeader component /// public RenderFragment? HeaderToolbarTemplate { get; set; } /// - /// 获得/设置 自定义组件 + /// Gets or sets the custom component /// public BootstrapDynamicComponent? Component { get; set; } /// - /// 获得/设置 保存按钮图标 默认 null 使用当前主题图标 + /// Gets or sets the icon of the save button, default is null and uses the current theme icon /// public string? SaveButtonIcon { get; set; } /// - /// 获得/设置 保存按钮文本 + /// Gets or sets the text of the save button /// public string? SaveButtonText { get; set; } /// - /// 获得/设置 保存按钮回调方法 + /// Gets or sets the callback method for the save button /// public Func>? OnSaveAsync { get; set; } /// - /// 获得/设置 关闭按钮图标 默认 null 使用当前主题图标 + /// Gets or sets the icon of the close button, default is null and uses the current theme icon /// public string? CloseButtonIcon { get; set; } /// - /// 获得/设置 关闭按钮文本 + /// Gets or sets the text of the close button /// public string? CloseButtonText { get; set; } /// - /// 获得/设置 关闭弹窗回调方法 + /// Gets or sets the callback method for closing the dialog /// public Func? OnCloseAsync { get; set; } /// - /// 获得/设置 保存成功后是否自动关闭弹窗 默认 true 自动关闭 + /// Gets or sets whether to automatically close the dialog after saving successfully, default is true /// public bool IsAutoCloseAfterSave { get; set; } = true; /// - /// 获得/设置 是否可以拖拽弹窗 默认 false 不可以拖动 + /// Gets or sets whether the dialog can be dragged, default is false /// public bool IsDraggable { get; set; } /// - /// 获得/设置 弹窗已显示时回调此方法 + /// Gets or sets the callback method when the dialog is shown /// public Func? OnShownAsync { get; set; } /// - /// 获得/设置 是否显示导出 Pdf 按钮 默认为 false 不显示 + /// Gets or sets whether to show the export PDF button, default is false /// public bool ShowExportPdfButton { get; set; } /// - /// 获得/设置 Header 中是否显示导出 Pdf 按钮 默认 false 不显示 + /// Gets or sets whether to show the export PDF button in the header, default is false /// public bool ShowExportPdfButtonInHeader { get; set; } /// - /// 获得/设置 导出 Pdf 按钮配置项 + /// Gets or sets the configuration options for the export PDF button /// public ExportPdfButtonOptions? ExportPdfButtonOptions { get; set; } /// - /// 关闭弹窗方法 + /// Method to close the dialog /// public async Task CloseDialogAsync() { @@ -204,7 +204,7 @@ public async Task CloseDialogAsync() } /// - /// 将参数转换为组件属性方法 + /// Method to convert parameters to component attributes /// /// public Dictionary ToAttributes() From 038c79df723793945a75b5ef1599a08b41d0f48d Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Wed, 5 Mar 2025 09:28:16 +0800 Subject: [PATCH 2/7] =?UTF-8?q?refactor:=20=E5=A2=9E=E5=8A=A0=20IsFade=20?= =?UTF-8?q?=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor/Components/Dialog/DialogOption.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/BootstrapBlazor/Components/Dialog/DialogOption.cs b/src/BootstrapBlazor/Components/Dialog/DialogOption.cs index 07c20b9fbe3..3ebbc45547d 100644 --- a/src/BootstrapBlazor/Components/Dialog/DialogOption.cs +++ b/src/BootstrapBlazor/Components/Dialog/DialogOption.cs @@ -67,6 +67,11 @@ public class DialogOption /// public bool ShowHeaderCloseButton { get; set; } = true; + /// + /// Gets or sets whether to enable fade animation, default is true + /// + public bool IsFade { get; set; } = true; + /// /// Gets or sets whether to support closing the dialog with the ESC key, default is true /// From 7327b8bdac6f1f63d7ca4e1a345c25c17dec267e Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Wed, 5 Mar 2025 09:30:47 +0800 Subject: [PATCH 3/7] =?UTF-8?q?refactor:=20=E5=A2=9E=E5=8A=A0=20IsFade=20?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Dialog/Dialog.razor | 3 ++- .../Components/Dialog/Dialog.razor.cs | 17 ++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/BootstrapBlazor/Components/Dialog/Dialog.razor b/src/BootstrapBlazor/Components/Dialog/Dialog.razor index d237e397a31..f5b147441f2 100644 --- a/src/BootstrapBlazor/Components/Dialog/Dialog.razor +++ b/src/BootstrapBlazor/Components/Dialog/Dialog.razor @@ -1,7 +1,8 @@ @namespace BootstrapBlazor.Components @inherits BootstrapComponentBase - + @for (var index = 0; index < DialogParameters.Keys.Count; index++) { @RenderDialog(index, DialogParameters.Keys.ElementAt(index)) diff --git a/src/BootstrapBlazor/Components/Dialog/Dialog.razor.cs b/src/BootstrapBlazor/Components/Dialog/Dialog.razor.cs index aaec0956cb0..d4c569de136 100644 --- a/src/BootstrapBlazor/Components/Dialog/Dialog.razor.cs +++ b/src/BootstrapBlazor/Components/Dialog/Dialog.razor.cs @@ -21,9 +21,11 @@ public partial class Dialog : IDisposable /// private Dictionary, (bool IsKeyboard, bool IsBackdrop)> DialogParameters { get; } = []; - private bool IsKeyboard { get; set; } + private bool _isKeyboard = false; - private bool IsBackdrop { get; set; } + private bool _isBackdrop = false; + + private bool _isFade = true; /// /// DialogServices 服务实例 @@ -92,15 +94,16 @@ private async Task Show(DialogOption option) // 多弹窗支持 var p = DialogParameters.LastOrDefault(); CurrentParameter = p.Key; - IsKeyboard = p.Value.IsKeyboard; - IsBackdrop = p.Value.IsBackdrop; + _isKeyboard = p.Value.IsKeyboard; + _isBackdrop = p.Value.IsBackdrop; StateHasChanged(); } }; - IsKeyboard = option.IsKeyboard; - IsBackdrop = option.IsBackdrop; + _isKeyboard = option.IsKeyboard; + _isBackdrop = option.IsBackdrop; + _isFade = option.IsFade; option.Modal = ModalContainer; @@ -167,7 +170,7 @@ private async Task Show(DialogOption option) CurrentParameter = parameters; // 添加 ModalDialog 到容器中 - DialogParameters.Add(parameters, (IsKeyboard, IsBackdrop)); + DialogParameters.Add(parameters, (_isKeyboard, _isBackdrop)); await InvokeAsync(StateHasChanged); } From 6748605b98cfdf9ab0732da1b4f72c5ae6eb434b Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Wed, 5 Mar 2025 09:38:35 +0800 Subject: [PATCH 4/7] =?UTF-8?q?test:=20=E6=9B=B4=E6=96=B0=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/UnitTest/Components/ModalTest.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/UnitTest/Components/ModalTest.cs b/test/UnitTest/Components/ModalTest.cs index 327a57c2201..e21de85fc46 100644 --- a/test/UnitTest/Components/ModalTest.cs +++ b/test/UnitTest/Components/ModalTest.cs @@ -18,6 +18,7 @@ public void IsBackdrop_Ok() pb.Add(m => m.IsFade, false); }); Assert.DoesNotContain("static", cut.Markup); + Assert.DoesNotContain("modal fade", cut.Markup); cut.SetParametersAndRender(pb => { @@ -34,6 +35,7 @@ public void Toggle_Ok() pb.AddChildContent(); }); cut.InvokeAsync(async () => await cut.Instance.Toggle()); + Assert.Contains("modal fade", cut.Markup); Assert.Contains("modal-dialog", cut.Markup); } From 96ec39c25edc1f4aea72bfdbe8e326d95f2f24d4 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Wed, 5 Mar 2025 09:40:19 +0800 Subject: [PATCH 5/7] =?UTF-8?q?test:=20=E6=9B=B4=E6=96=B0=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/UnitTest/Components/DialogTest.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/UnitTest/Components/DialogTest.cs b/test/UnitTest/Components/DialogTest.cs index 30399084d30..067aca4a161 100644 --- a/test/UnitTest/Components/DialogTest.cs +++ b/test/UnitTest/Components/DialogTest.cs @@ -58,6 +58,7 @@ await cut.InvokeAsync(() => dialog.Show(new DialogOption() ShowExportPdfButton = true, ShowExportPdfButtonInHeader = true, ExportPdfButtonOptions = new(), + IsFade = false, OnCloseAsync = () => { closed = true; @@ -65,6 +66,9 @@ await cut.InvokeAsync(() => dialog.Show(new DialogOption() } })); + // 由于设置了 IsFade=false Modal 不应该渲染 fade 样式 + Assert.DoesNotContain("modal fade", modal.Markup); + // 由于设置了 ShowMaximizeButton 导致 ShowResize 参数失效 Assert.DoesNotContain(" Date: Wed, 5 Mar 2025 09:40:53 +0800 Subject: [PATCH 6/7] chore: bump version 9.4.4 --- src/BootstrapBlazor/BootstrapBlazor.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BootstrapBlazor/BootstrapBlazor.csproj b/src/BootstrapBlazor/BootstrapBlazor.csproj index bf5f5cb5aca..ee9e70bc063 100644 --- a/src/BootstrapBlazor/BootstrapBlazor.csproj +++ b/src/BootstrapBlazor/BootstrapBlazor.csproj @@ -1,7 +1,7 @@ - 9.4.3-beta04 + 9.4.4 From 6ea1cbda542dd8cddc8cc829c2288a97394d4272 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Wed, 5 Mar 2025 09:51:26 +0800 Subject: [PATCH 7/7] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Dialog/Dialog.razor | 4 +- .../Components/Dialog/Dialog.razor.cs | 73 ++++++++----------- 2 files changed, 32 insertions(+), 45 deletions(-) diff --git a/src/BootstrapBlazor/Components/Dialog/Dialog.razor b/src/BootstrapBlazor/Components/Dialog/Dialog.razor index f5b147441f2..749452aa414 100644 --- a/src/BootstrapBlazor/Components/Dialog/Dialog.razor +++ b/src/BootstrapBlazor/Components/Dialog/Dialog.razor @@ -1,8 +1,8 @@ @namespace BootstrapBlazor.Components @inherits BootstrapComponentBase - + @for (var index = 0; index < DialogParameters.Keys.Count; index++) { @RenderDialog(index, DialogParameters.Keys.ElementAt(index)) diff --git a/src/BootstrapBlazor/Components/Dialog/Dialog.razor.cs b/src/BootstrapBlazor/Components/Dialog/Dialog.razor.cs index d4c569de136..296f1a54100 100644 --- a/src/BootstrapBlazor/Components/Dialog/Dialog.razor.cs +++ b/src/BootstrapBlazor/Components/Dialog/Dialog.razor.cs @@ -6,55 +6,42 @@ namespace BootstrapBlazor.Components; /// -/// Dialog 对话框组件 +/// Dialog component /// public partial class Dialog : IDisposable { - /// - /// 获得/设置 Modal 容器组件实例 - /// - [NotNull] - private Modal? ModalContainer { get; set; } - - /// - /// 获得/设置 弹出对话框实例集合 - /// - private Dictionary, (bool IsKeyboard, bool IsBackdrop)> DialogParameters { get; } = []; - - private bool _isKeyboard = false; - - private bool _isBackdrop = false; - - private bool _isFade = true; - - /// - /// DialogServices 服务实例 - /// [Inject] [NotNull] private DialogService? DialogService { get; set; } [NotNull] - private Func? OnShownAsync { get; set; } + private Modal? _modal = null; [NotNull] - private Func? OnCloseAsync { get; set; } + private Func? _onShownAsync = null; - private Dictionary? CurrentParameter { get; set; } + [NotNull] + private Func? _onCloseAsync = null; + + private readonly Dictionary, (bool IsKeyboard, bool IsBackdrop)> DialogParameters = []; + private Dictionary? _currentParameter; + private bool _isKeyboard = false; + private bool _isBackdrop = false; + private bool _isFade = true; /// - /// OnInitialized 方法 + /// /// protected override void OnInitialized() { base.OnInitialized(); - // 注册 Dialog 弹窗事件 + // Register Dialog popup event DialogService.Register(this, Show); } /// - /// OnAfterRenderAsync 方法 + /// /// /// /// @@ -62,15 +49,15 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { await base.OnAfterRenderAsync(firstRender); - if (CurrentParameter != null) + if (_currentParameter != null) { - await ModalContainer.Show(); + await _modal.Show(); } } private async Task Show(DialogOption option) { - OnShownAsync = async () => + _onShownAsync = async () => { if (option.OnShownAsync != null) { @@ -78,22 +65,22 @@ private async Task Show(DialogOption option) } }; - OnCloseAsync = async () => + _onCloseAsync = async () => { - // 回调 OnCloseAsync + // Callback OnCloseAsync if (option.OnCloseAsync != null) { await option.OnCloseAsync(); } - // 移除当前 DialogParameter - if (CurrentParameter != null) + // Remove current DialogParameter + if (_currentParameter != null) { - DialogParameters.Remove(CurrentParameter); + DialogParameters.Remove(_currentParameter); - // 多弹窗支持 + // Support for multiple dialogs var p = DialogParameters.LastOrDefault(); - CurrentParameter = p.Key; + _currentParameter = p.Key; _isKeyboard = p.Value.IsKeyboard; _isBackdrop = p.Value.IsBackdrop; @@ -105,7 +92,7 @@ private async Task Show(DialogOption option) _isBackdrop = option.IsBackdrop; _isFade = option.IsFade; - option.Modal = ModalContainer; + option.Modal = _modal; var parameters = option.ToAttributes(); var content = option.BodyTemplate ?? option.Component?.Render(); @@ -166,10 +153,10 @@ private async Task Show(DialogOption option) } } - // 保存当前 Dialog 参数 - CurrentParameter = parameters; + // Save current Dialog parameters + _currentParameter = parameters; - // 添加 ModalDialog 到容器中 + // Add ModalDialog to the container DialogParameters.Add(parameters, (_isKeyboard, _isBackdrop)); await InvokeAsync(StateHasChanged); } @@ -183,7 +170,7 @@ private static RenderFragment RenderDialog(int index, Dictionary }; /// - /// Dispose 方法 + /// Dispose method /// /// protected virtual void Dispose(bool disposing) @@ -195,7 +182,7 @@ protected virtual void Dispose(bool disposing) } /// - /// Dispose 方法 + /// /// public void Dispose() {