Skip to content
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8671b84
chore: 更新 OctIcon 支持 Color 参数
ArgoZhang Feb 4, 2025
6f2c35d
doc: 更新图标示例
ArgoZhang Feb 4, 2025
4dd6a70
chore: 更新依赖包
ArgoZhang Feb 4, 2025
16f506c
feat: 增加 SearchContext 精简代码逻辑
ArgoZhang Feb 4, 2025
6c358e1
style: 增加样式
ArgoZhang Feb 4, 2025
50dc40f
doc: 更新示例代码
ArgoZhang Feb 4, 2025
1387d8e
doc: 更新示例文档
ArgoZhang Feb 4, 2025
44897ff
test: 增加单元测试
ArgoZhang Feb 4, 2025
56a943b
test: 更新单元测试
ArgoZhang Feb 4, 2025
64621a6
chore: bump version 9.3.1-beta07
ArgoZhang Feb 4, 2025
955968c
test: 更新单元测试
ArgoZhang Feb 4, 2025
b298db7
feat: 增加 ButtonTemplate 参数
ArgoZhang Feb 4, 2025
045367c
feat: 增加 ShowClearIcon 参数
ArgoZhang Feb 4, 2025
eab5314
refactor: 增加 form-control-group 节点
ArgoZhang Feb 4, 2025
6406363
style: 更新样式
ArgoZhang Feb 4, 2025
02be9e3
feat: 增加 PrefixButtonTemplate 参数
ArgoZhang Feb 4, 2025
e3f3b1d
refactor: 增加 PrefixButtonTemplate 逻辑
ArgoZhang Feb 4, 2025
77cbde3
style: 增加 bb-search-icon-input-padding-right 变量
ArgoZhang Feb 4, 2025
9fcfa29
doc: 增加示例
ArgoZhang Feb 4, 2025
d1ddec6
refactor: 更改 IsClearable 参数
ArgoZhang Feb 5, 2025
6c26131
refactor: 调整 ButtonTemplate 位置
ArgoZhang Feb 5, 2025
a4ac12b
doc: 增加示例代码
ArgoZhang Feb 5, 2025
18e26a1
doc: 更新示例
ArgoZhang Feb 5, 2025
c3c9449
doc: 增加文档注释
ArgoZhang Feb 5, 2025
de7faf6
doc: 增加注释文档多语言
ArgoZhang Feb 5, 2025
22d7007
test: 更新单元测试
ArgoZhang Feb 5, 2025
37433a9
refactor: 重构 DOM 结构精简样式
ArgoZhang Feb 4, 2025
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
6 changes: 3 additions & 3 deletions src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="BootstrapBlazor.AntDesignIcon" Version="9.0.1" />
<PackageReference Include="BootstrapBlazor.AntDesignIcon" Version="9.0.2" />
<PackageReference Include="BootstrapBlazor.AzureOpenAI" Version="9.0.0" />
<PackageReference Include="BootstrapBlazor.AzureTranslator" Version="9.0.0" />
<PackageReference Include="BootstrapBlazor.BaiduSpeech" Version="9.0.0" />
Expand All @@ -32,7 +32,7 @@
<PackageReference Include="BootstrapBlazor.CherryMarkdown" Version="9.0.0" />
<PackageReference Include="BootstrapBlazor.Dock" Version="9.0.0" />
<PackageReference Include="BootstrapBlazor.DockView" Version="9.0.3" />
<PackageReference Include="BootstrapBlazor.DriverJs" Version="9.0.1" />
<PackageReference Include="BootstrapBlazor.DriverJs" Version="9.0.3" />
<PackageReference Include="BootstrapBlazor.ElementIcon" Version="9.0.1" />
<PackageReference Include="BootstrapBlazor.FileViewer" Version="9.0.0" />
<PackageReference Include="BootstrapBlazor.FontAwesome" Version="9.0.2" />
Expand All @@ -48,7 +48,7 @@
<PackageReference Include="BootstrapBlazor.Mermaid" Version="9.0.3" />
<PackageReference Include="BootstrapBlazor.MindMap" Version="9.1.3" />
<PackageReference Include="BootstrapBlazor.MouseFollower" Version="9.0.1" />
<PackageReference Include="BootstrapBlazor.OctIcon" Version="9.0.1" />
<PackageReference Include="BootstrapBlazor.OctIcon" Version="9.0.2" />
<PackageReference Include="BootstrapBlazor.OnScreenKeyboard" Version="9.0.1" />
<PackageReference Include="BootstrapBlazor.PdfReader" Version="9.0.0" />
<PackageReference Include="BootstrapBlazor.Player" Version="9.0.0" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@typeparam TValue

<Button Text="Clear1" OnClick="OnClickClear"></Button>
<Button Text="Search1" OnClick="OnClickSearch"></Button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// 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([email protected]) Website: https://www.blazor.zone

namespace BootstrapBlazor.Server.Components.Components;

/// <summary>
/// SearchButtonTemplateDemo 示例组件
/// </summary>
public partial class SearchButtonTemplateDemo<TValue>
{
/// <summary>
/// 获得/设置 <see cref="SearchContext{TValue}"/> 实例"/>
/// </summary>
[Parameter, EditorRequired, NotNull]
public SearchContext<TValue>? Context { get; set; }

[Inject, NotNull]
private ToastService? ToastService { get; set; }

private async Task OnClickSearch()
{
await Context.OnSearchAsync();

await ToastService.Information("Search-ButtonTemplate", "Click Search1 Button");
}

private async Task OnClickClear()
{
await Context.OnClearAsync();

await ToastService.Information("Search-ButtonTemplate", "Click Clear1 Button");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
<Pre>&lt;link href="_content/BootstrapBlazor.AntDesignIcon/BootstrapBlazor.AntDesignIcon.bundle.scp.css" rel="stylesheet"&gt;</Pre>

<div class="mb-2">
<AntDesignIcon Category="AntDesignIconCategory.Outlined" Name="github"></AntDesignIcon>
<AntDesignIcon Category="AntDesignIconCategory.Filled" Name="left-circle"></AntDesignIcon>
<AntDesignIcon Category="AntDesignIconCategory.Outlined" Name="left-circle"></AntDesignIcon>
</div>

<Pre>&lt;AntDesignIcon Category="AntDesignIconCategory.Outlined" Name="github"&gt;&lt;/AntDesignIcon&gt;</Pre>
Expand Down
99 changes: 99 additions & 0 deletions src/BootstrapBlazor.Server/Components/Samples/Searches.razor
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,106 @@
</Search>
</div>
</div>
</DemoBlock>

<DemoBlock Title="@Localizer["SearchesIconTemplateTitle"]"
Introduction="@Localizer["SearchesIconTemplateIntro"]"
Name="IconTemplate">
<section ignore>
<p>@((MarkupString)Localizer["SearchesIconTemplateDesc"].Value)</p>
</section>
<div class="row g-3">
<div class="col-12">
<Search PlaceHolder="@Localizer["SearchesPlaceHolder"]"
OnSearch="@OnModelSearch"
IsClearable="true" ShowSearchButton="false"
ShowPrefixIcon="true" PrefixIcon="fa fa-flag">
<IconTemplate>
<i class="search-icon fa-solid fa-camera" @onclick="() => OnClickCamera(context)"></i>
</IconTemplate>
</Search>
</div>
</div>
</DemoBlock>

<DemoBlock Title="@Localizer["SearchesButtonTemplateTitle"]"
Introduction="@Localizer["SearchesButtonTemplateIntro"]"
Name="ButtonTemplate">
<section ignore>
<p>@((MarkupString)Localizer["SearchesButtonTemplateDesc"].Value)</p>
<p>@((MarkupString)Localizer["SearchesButtonTemplateDesc2"].Value)</p>
<Pre>[Parameter, EditorRequired, NotNull]
public SearchContext&lt;TValue&gt;? Context { get; set; }

[Inject, NotNull]
private ToastService? ToastService { get; set; }

private async Task OnClickSearch()
{
await Context.OnSearchAsync();

await ToastService.Information("Search-ButtonTemplate", "Click Search1 Button");
}

private async Task OnClickClear()
{
await Context.OnClearAsync();

await ToastService.Information("Search-ButtonTemplate", "Click Clear1 Button");
}</Pre>
</section>
<div class="row g-3">
<div class="col-12">
<Search PlaceHolder="@Localizer["SearchesPlaceHolder"]"
OnSearch="@OnModelSearch"
IsClearable="true"
ShowPrefixIcon="true" PrefixIcon="fa fa-flag">
<PrefixButtonTemplate>
<Button Text="Text1"></Button>
<Button Text="Text2"></Button>
</PrefixButtonTemplate>
<ButtonTemplate>
<SearchButtonTemplateDemo Context="context"></SearchButtonTemplateDemo>
</ButtonTemplate>
</Search>
</div>
</div>
</DemoBlock>

<DemoBlock Title="@Localizer["SearchesIsClearableTitle"]"
Introduction="@Localizer["SearchesIsClearableIntro"]"
Name="ButtonTemplate">
<section ignore>
<div class="row g-3">
<div class="col-12 col-sm-4">
<BootstrapInputGroup>
<BootstrapInputGroupLabel DisplayText="IsClearable"></BootstrapInputGroupLabel>
<Checkbox @bind-Value="_isClearable"></Checkbox>
</BootstrapInputGroup>
</div>
<div class="col-12 col-sm-4">
<BootstrapInputGroup>
<BootstrapInputGroupLabel DisplayText="ShowClearButton"></BootstrapInputGroupLabel>
<Checkbox @bind-Value="_showClearButton"></Checkbox>
</BootstrapInputGroup>
</div>
<div class="col-12 col-sm-4">
<BootstrapInputGroup>
<BootstrapInputGroupLabel DisplayText="ShowSearchButton"></BootstrapInputGroupLabel>
<Checkbox @bind-Value="_showSearchButton"></Checkbox>
</BootstrapInputGroup>
</div>
</div>
</section>
<div class="row g-3">
<div class="col-12 col-sm-6">
<Search PlaceHolder="@Localizer["SearchesPlaceHolder"]"
OnSearch="@OnModelSearch"
IsClearable="_isClearable" ShowClearButton="_showClearButton" ShowSearchButton="_showSearchButton"
ShowPrefixIcon="true" PrefixIcon="fa-brands fa-github">
</Search>
</div>
</div>
</DemoBlock>

<AttributeTable Items="@GetAttributes()" />
44 changes: 41 additions & 3 deletions src/BootstrapBlazor.Server/Components/Samples/Searches.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 Searches
{
[Inject, NotNull]
private ToastService? ToastService { get; set; }

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

Expand Down Expand Up @@ -78,6 +81,17 @@ private async Task<IEnumerable<Foo>> OnSearchFoo(string searchText)
: Enumerable.Range(1, 10).Select(i => LocalizerFoo["Foo.Name", $"{i:d4}"].Value).ToList();
}

private async Task OnClickCamera(SearchContext<string?> context)
{
await Task.Delay(10);

await ToastService.Information("Custom IconTemplate", "Click custom icon");
}

private bool _isClearable = true;
private bool _showClearButton = false;
private bool _showSearchButton = false;

/// <summary>
/// 获得属性方法
/// </summary>
Expand All @@ -93,11 +107,35 @@ private AttributeItem[] GetAttributes() =>
},
new()
{
Name="SearchButtonLoadingIcon",
Description = Localizer["SearchesButtonLoadingIcon"],
Name="IsClearable",
Description = Localizer["SearchesIsClearable"],
Type = "bool",
ValueList = "true|false",
DefaultValue = "false"
},
new()
{
Name="ClearIcon",
Description = Localizer["SearchesClearIcon"],
Type = "string",
ValueList = " — ",
DefaultValue = "fa-fw fa-spin fa-solid fa-spinner"
DefaultValue = " — "
},
new()
{
Name="PrefixButtonTemplate",
Description = Localizer["SearchesPrefixButtonTemplate"],
Type = "RenderFragment",
ValueList = " — ",
DefaultValue = " — "
},
new()
{
Name="ButtonTemplate",
Description = Localizer["SearchesButtonTemplate"],
Type = "RenderFragment",
ValueList = " — ",
DefaultValue = " — "
},
new() {
Name = "ClearButtonIcon",
Expand Down
15 changes: 14 additions & 1 deletion src/BootstrapBlazor.Server/Locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -4226,7 +4226,20 @@
"SearchesItemTemplateIntro": "By setting <code>ItemTemplate</code> and matching generic data, you can achieve any desired effect. In this example, by searching for any keyword, the backend calls any third-party search results and displays them. After selecting the search item, you can handle it yourself through the <code>OnSelectedItemChanged</code> callback method",
"SearchesShowPrefixIconTitle": "ShowPrefixIcon",
"SearchesShowPrefixIconIntro": "Control whether to show the prefix icon by setting the <code>ShowPrefixIcon</code> parameter",
"SearchesShowPrefixIconDescription": "You can customize the prefix through <code>PrefixIconTemplate</code>. In this example, the <code>Svg</code> icon is used through the prefix template."
"SearchesShowPrefixIconDescription": "You can customize the prefix through <code>PrefixIconTemplate</code>. In this example, the <code>Svg</code> icon is used through the prefix template.",
"SearchesButtonTemplateTitle": "Button Template",
"SearchesButtonTemplateIntro": "Customize the buttons displayed by the component by setting <code>ButtonTemplate</code>",
"SearchesButtonTemplateDesc": "Customize the buttons displayed in front of the component by setting <code>PrefixButtonTemplate</code>",
"SearchesButtonTemplateDesc2": "In a custom template, you can call the <code>OnClear</code> <code>OnSearch</code> method inside the <code>Search</code> component with the context.",
"SearchesIsClearableTitle": "IsClearable",
"SearchesIsClearableIntro": "Display the clear icon by setting <code>IsClearable=\"true\"</code>",
"SearchesIsClearable": "Whether to display the clear icon",
"SearchesClearIcon": "Clear Icon",
"SearchesPrefixButtonTemplate": "Prefix button template",
"SearchesButtonTemplate": "Button template",
"SearchesIconTemplateTitle": "Icon Template",
"SearchesIconTemplateIntro": "Customize the icon displayed by the component by setting <code>IconTemplate</code>",
"SearchesIconTemplateDesc": "The search component context <code>SearchContext&lt;string&gt;</code> provides the <code>OnClear</code> <code>OnSearch</code> methods within the component"
},
"BootstrapBlazor.Server.Components.Samples.Titles": {
"Title": "Title",
Expand Down
15 changes: 14 additions & 1 deletion src/BootstrapBlazor.Server/Locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -4226,7 +4226,20 @@
"SearchesItemTemplateIntro": "通过设置 <code>ItemTemplate</code> 配合泛型数据可以做出自己想要的任何效果,本例中通过搜索任意关键字,后台调用任意第三方搜索结果并且进行展示,选中搜索项后通过 <code>OnSelectedItemChanged</code> 回调方法可以自行处理",
"SearchesShowPrefixIconTitle": "显示前缀图标",
"SearchesShowPrefixIconIntro": "通过设置 <code>ShowPrefixIcon</code> 参数控制是否显示前缀图标",
"SearchesShowPrefixIconDescription": "可以通过 <code>PrefixIconTemplate</code> 自定义前缀,本例中通过前缀模板使用 <code>Svg</code> 图标"
"SearchesShowPrefixIconDescription": "可以通过 <code>PrefixIconTemplate</code> 自定义前缀,本例中通过前缀模板使用 <code>Svg</code> 图标",
"SearchesButtonTemplateTitle": "按钮模板",
"SearchesButtonTemplateIntro": "通过设置 <code>ButtonTemplate</code> 自定义组件显示的按钮",
"SearchesButtonTemplateDesc": "通过设置 <code>PrefixButtonTemplate</code> 自定义组件前置显示的按钮",
"SearchesButtonTemplateDesc2": "在自定义模板中可以通过关联参数调用 <code>Search</code> 组件内部的 <code>OnClear</code> <code>OnSearch</code> 方法",
"SearchesIsClearableTitle": "IsClearable",
"SearchesIsClearableIntro": "通过设置 <code>IsClearable=\"true\"</code> 显示清空小图标",
"SearchesIsClearable": "是否显示清空小按钮",
"SearchesClearIcon": "清空图标",
"SearchesPrefixButtonTemplate": "前置按钮模板",
"SearchesButtonTemplate": "按钮模板",
"SearchesIconTemplateTitle": "图标模板",
"SearchesIconTemplateIntro": "通过设置 <code>IconTemplate</code> 自定义组件显示的图标",
"SearchesIconTemplateDesc": "搜索组件上下文 <code>SearchContext&lt;string&gt;</code> 提供了组件内部的 <code>OnClear</code> <code>OnSearch</code> 方法"
},
"BootstrapBlazor.Server.Components.Samples.Titles": {
"Title": "Title 网站标题",
Expand Down
64 changes: 42 additions & 22 deletions src/BootstrapBlazor/Components/Search/Search.razor
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,48 @@

<div @attributes="@AdditionalAttributes" class="@ClassString" id="@Id">
<div class="input-group">
<input @attributes="AdditionalAttributes" id="@InputId" class="@ClassName" autocomplete="off" type="text"
data-bs-toggle="@ToggleString" data-bs-placement="@PlacementString"
data-bs-offset="@OffsetString" data-bs-custom-class="@CustomClassString"
data-bb-auto-dropdown-focus="@ShowDropdownListOnFocusString"
data-bb-skip-esc="@SkipEscString" data-bb-skip-enter="@SkipEnterString"
data-bb-scroll-behavior="@ScrollIntoViewBehaviorString"
data-bb-input="@UseInputString"
value="@_displayText"
placeholder="@PlaceHolder" disabled="@Disabled" @ref="FocusElement" />
@if (PrefixButtonTemplate != null)
{
@PrefixButtonTemplate(_context)
}
<div class="form-control-group form-control">
@if (ShowPrefixIcon)
{
<div class="search-prefix-icon">
@if (PrefixIconTemplate != null)
{
@PrefixIconTemplate(_context)
}
else
{
<i class="@PrefixIcon"></i>
}
</div>
}
<input id="@InputId" class="search-input" autocomplete="off" type="text"
data-bs-toggle="@ToggleString" data-bs-placement="@PlacementString"
data-bs-offset="@OffsetString" data-bs-custom-class="@CustomClassString"
data-bb-auto-dropdown-focus="@ShowDropdownListOnFocusString"
data-bb-skip-esc="@SkipEscString" data-bb-skip-enter="@SkipEnterString"
data-bb-scroll-behavior="@ScrollIntoViewBehaviorString"
data-bb-input="@UseInputString"
value="@_displayText"
placeholder="@PlaceHolder" disabled="@Disabled" @ref="FocusElement" />
@if (IsClearable)
{
<div class="search-icon search-clear-icon">
<i class="@ClearIcon" @onclick="OnClearClick" aria-label="Clear"></i>
</div>
}
@if (IconTemplate != null)
{
@IconTemplate(_context)
}
</div>
@if (ButtonTemplate != null)
{
@ButtonTemplate(_context)
}
@if (ShowClearButton)
{
<Button Color="ClearButtonColor" Text="@ClearButtonText" Icon="@ClearButtonIcon" OnClick="OnClearClick" aria-label="Clear"></Button>
Expand All @@ -22,19 +55,6 @@
<Button Color="SearchButtonColor" Text="@SearchButtonText" Icon="@ButtonIcon" OnClick="OnSearchClick" aria-label="Search"></Button>
}
</div>
@if (ShowPrefixIcon)
{
<div class="search-prefix-icon">
@if (PrefixIconTemplate != null)
{
@PrefixIconTemplate
}
else
{
<i class="@PrefixIcon"></i>
}
</div>
}
<ul class="dropdown-menu">
@foreach (var item in _filterItems)
{
Expand Down
Loading
Loading