Skip to content

Commit

Permalink
feat(Dropdown): add IsAsync parameter (#5324)
Browse files Browse the repository at this point in the history
* refactor: update html element tag name

* test: 更新单元测试

* doc: 更新参数注释

* feat(Dropdown): add IsAsync parameter

* refactor: 精简代码

提高代码可读性

* refactor: 代码重构

* feat: 实现 IsAsync 逻辑

* doc: 增加 IsAsync 文档

* feat: 分离按钮支持默认颜色

* feat: 异步图标显示逻辑

* refactor: 增加 span 包裹元素

* doc: 增加文档

* feat: 增加图标赋值逻辑

* refactor: 使用父类服务

* test: 增加单元测试

* chore: bump version 9.3.1-beta10

Co-Authored-By: ice6 <[email protected]>
  • Loading branch information
ArgoZhang and ice6 authored Feb 8, 2025
1 parent 0f7be01 commit 1c4bc58
Show file tree
Hide file tree
Showing 11 changed files with 175 additions and 67 deletions.
4 changes: 4 additions & 0 deletions src/BootstrapBlazor.Server/Components/Samples/Dropdowns.razor
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
</div>
</DemoBlock>

<DemoBlock Title="@Localizer["IsAsyncTitle"]" Introduction='@Localizer["IsAsyncIntro"]' Name="IsAsync">
<Dropdown TValue="string" Items="Items" ShowSplit="true" IsAsync="true" OnClickWithoutRender="OnIsAsyncClick"></Dropdown>
</DemoBlock>

<DemoBlock Title="@Localizer["SizeTitle"]" Introduction="@Localizer["SizeIntro"]" Name="Size">
<div class="row g-3">
<div class="col-6 col-sm-4 col-md-3 col-xl-auto">
Expand Down
20 changes: 20 additions & 0 deletions src/BootstrapBlazor.Server/Components/Samples/Dropdowns.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ namespace BootstrapBlazor.Server.Components.Samples;
/// </summary>
public sealed partial class Dropdowns
{
[Inject, NotNull]
private ToastService? ToastService { get; set; }

[NotNull]
private ConsoleLogger? Logger { get; set; }

Expand Down Expand Up @@ -142,6 +145,15 @@ private async Task OnCascadeBindSelectClick(SelectedItem item)
StateHasChanged();
}

private async Task OnIsAsyncClick()
{
// 模拟异步延时
await Task.Delay(1000);

// 提示任务完成
await ToastService.Success("Dropdown IsAsync", "Job done!");
}

/// <summary>
/// GetAttributes
/// </summary>
Expand Down Expand Up @@ -220,6 +232,14 @@ private AttributeItem[] GetAttributes() =>
DefaultValue = " false "
},
new()
{
Name = "IsAsync",
Description = Localizer["AttributeIsAsync"],
Type = "boolean",
ValueList = " — ",
DefaultValue = "false"
},
new()
{
Name = "Size",
Description = Localizer["AttributeSize"],
Expand Down
5 changes: 4 additions & 1 deletion src/BootstrapBlazor.Server/Locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -1763,6 +1763,8 @@
"SplitIntro": "You can create a split drop-down menu with tags similar to a single button drop-down menu, and add ShowSplit='true' when you use a split component. Insert this symbol as a drop-down The options are handled at appropriate intervals (distance).",
"SizeTitle": "Size definition",
"SizeIntro": "The drop-down menu has a variety of size specifications to choose from <code>Size</code> attributes, including preset and split button drop-down menus.",
"IsAsyncTitle": "Asynchronous request button",
"IsAsyncIntro": "By setting whether the <code>isAsync</code> property button is <b>asynchronous request button by setting whether the is</b> <code>false</code> by default",
"DirectionTitle": "Expanding direction",
"DirectionIntro": "Add the style of <code>Direction='Direction.Dropup'</code> to make the drop-down menu expand upward.",
"AlignmentTitle": "Menu alignment",
Expand All @@ -1788,6 +1790,7 @@
"AttributeMenuItem": "Menu item rendering label",
"AttributeResponsive": "Menu alignment",
"AttributeShowSplit": "Split button drop-down menu",
"AttributeIsAsync": "whether it is an asynchronous button",
"AttributeSize": "Size",
"AttributeTagName": "Label",
"AttributeButtonTemplate": "The template of button",
Expand Down Expand Up @@ -2226,7 +2229,7 @@
"Block8Title": "Secondary encapsulation button",
"Block8Intro": "The button display text is set by setting the <code>Text</code> property of the <code>winButton</code> component, and the click button is the text on the right that shows the clicked button",
"Block9Title": "Asynchronous request button",
"Block9Intro": "By setting whether the <code>isAsync</code> property button is <b>asynchronous request button by setting whether the is</b> <code>false</code> by default",
"Block9Intro": "By setting whether the <code>isAsync</code> property button is <b>asynchronous request button by setting whether the is</b> <code>false</code> by default. <b>Note</b> This will only take effect when <code>ShowSplit=\"true\"</code> is set",
"ButtonAsyncDescription": "When the button is an asynchronous request button, the button is changed to disabled, and the <code>loading</code> small icon is displayed, returning to normal after the asynchronous request ends, in this case, after clicking the <b>asynchronous button</b>, the request load animation is displayed and returns to normal after 5 seconds",
"EventDesc1": "This event is triggered when the button is clicked",
"EventDesc2": "This event is triggered when the button is clicked and the current component is not refreshed for performance improvement",
Expand Down
3 changes: 3 additions & 0 deletions src/BootstrapBlazor.Server/Locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -1761,6 +1761,8 @@
"ColorIntro": "提供各种颜色的警告信息框 引用 <code>Color='Color.Primary'</code> 等颜色及样式类来定义下拉菜单的外在表现",
"SplitTitle": "分裂式按钮下拉菜单",
"SplitIntro": "可用与单个按钮下拉菜单近似的标记创建分裂式下拉菜单,添加 <code>ShowSplit='true'</code> 插入此符号为下拉选项作适当的间隔(距)处理。",
"IsAsyncTitle": "异步按钮",
"IsAsyncIntro": "通过设置 <code>IsAsync</code> 属性按钮是否为 <b>异步请求按钮</b>,默认为 <code>false</code>,<b>注意</b> 需要设置 <code>ShowSplit=\"true\"</code> 时才生效",
"SizeTitle": "尺寸大小定义",
"SizeIntro": "下拉菜单有各种大小规格可以选用 <code>Size</code> 属性,包括预设及分裂式按钮下拉菜单。",
"DirectionTitle": "展开方向",
Expand Down Expand Up @@ -1788,6 +1790,7 @@
"AttributeMenuItem": "菜单项渲染标签",
"AttributeResponsive": "菜单对齐",
"AttributeShowSplit": "分裂式按钮下拉菜单",
"AttributeIsAsync": "是否为异步按钮",
"AttributeSize": "尺寸",
"AttributeTagName": "标签",
"AttributeButtonTemplate": "按钮模板",
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>9.3.1-beta09</Version>
<Version>9.3.1-beta10</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
64 changes: 23 additions & 41 deletions src/BootstrapBlazor/Components/Button/Button.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,11 @@ public partial class Button : ButtonBase
[Parameter]
public bool IsAutoFocus { get; set; }

/// <summary>
/// 按钮点击回调方法,内置支持 IsAsync 开关
/// </summary>
protected EventCallback<MouseEventArgs> OnClickButton { get; set; }

/// <summary>
/// 获得/设置 html button 实例
/// </summary>
protected ElementReference ButtonElement { get; set; }

/// <summary>
/// OnInitialized 方法
/// </summary>
protected override void OnInitialized()
{
base.OnInitialized();

SetClickHandler();
}

/// <summary>
/// OnAfterRenderAsync 方法
/// </summary>
Expand All @@ -57,36 +42,33 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
}

/// <summary>
/// 设置 OnClickButton 方法
/// OnClickButton 方法
/// </summary>
protected virtual void SetClickHandler()
protected virtual async Task OnClickButton()
{
OnClickButton = EventCallback.Factory.Create<MouseEventArgs>(this, async () =>
if (IsAsync && ButtonType == ButtonType.Button)
{
if (IsAsync && ButtonType == ButtonType.Button)
{
IsAsyncLoading = true;
ButtonIcon = LoadingIcon;
IsDisabled = true;
}
IsAsyncLoading = true;
ButtonIcon = LoadingIcon;
IsDisabled = true;
}

if (IsAsync)
{
await Task.Run(() => InvokeAsync(HandlerClick));
}
else
{
await HandlerClick();
}
if (IsAsync)
{
await Task.Run(() => InvokeAsync(HandlerClick));
}
else
{
await HandlerClick();
}

// 恢复按钮
if (IsAsync && ButtonType == ButtonType.Button)
{
ButtonIcon = Icon;
IsDisabled = IsKeepDisabled;
IsAsyncLoading = false;
}
});
// 恢复按钮
if (IsAsync && ButtonType == ButtonType.Button)
{
ButtonIcon = Icon;
IsDisabled = IsKeepDisabled;
IsAsyncLoading = false;
}
}

/// <summary>
Expand All @@ -107,7 +89,7 @@ protected virtual async Task HandlerClick()
{
IsNotRender = true;
}
await OnClickWithoutRender.Invoke();
await OnClickWithoutRender();
}
if (OnClick.HasDelegate)
{
Expand Down
23 changes: 9 additions & 14 deletions src/BootstrapBlazor/Components/Button/CountButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// See the LICENSE file in the project root for more information.
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone

using Microsoft.AspNetCore.Components.Web;

namespace BootstrapBlazor.Components;

/// <summary>
Expand Down Expand Up @@ -33,21 +31,18 @@ public class CountButton : Button
/// <summary>
/// <inheritdoc/>
/// </summary>
protected override void SetClickHandler()
protected override async Task OnClickButton()
{
OnClickButton = EventCallback.Factory.Create<MouseEventArgs>(this, async () =>
{
IsAsyncLoading = true;
ButtonIcon = LoadingIcon;
IsDisabled = true;
IsAsyncLoading = true;
ButtonIcon = LoadingIcon;
IsDisabled = true;

await Task.Run(() => InvokeAsync(HandlerClick));
await UpdateCount();
await Task.Run(() => InvokeAsync(HandlerClick));
await UpdateCount();

IsDisabled = false;
ButtonIcon = Icon;
IsAsyncLoading = false;
});
IsDisabled = false;
ButtonIcon = Icon;
IsAsyncLoading = false;
}

/// <summary>
Expand Down
8 changes: 6 additions & 2 deletions src/BootstrapBlazor/Components/Dropdown/Dropdown.razor
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@

@if (IsShowLabel)
{
<BootstrapLabel for="@Id" ShowLabelTooltip="ShowLabelTooltip" Value="@DisplayText" />
<BootstrapLabel for="@Id" ShowLabelTooltip="ShowLabelTooltip" Value="@DisplayText"></BootstrapLabel>
}
<div @attributes="@AdditionalAttributes" id="@Id" class="@DirectionClassName">
<DynamicElement TagName="button" type="button" class="@ButtonClassName" data-bs-toggle="@DropdownToggle" disabled="@Disabled"
TriggerClick="ShowSplit" OnClick="OnClickButton">
@if (ButtonTemplate == null)
{
@ButtonText
@if (!string.IsNullOrEmpty(_buttonIcon))
{
<i class="@_buttonIcon"></i>
}
<span>@ButtonText</span>
}
else
{
Expand Down
Loading

0 comments on commit 1c4bc58

Please sign in to comment.