Skip to content
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
c8746fa
refactor: 重构代码消除警告信息
ArgoZhang Mar 19, 2025
2b9af5f
doc: 文档更改为英文注释
ArgoZhang Mar 19, 2025
aa5842d
feat: 增加 IsVirtualize 参数
ArgoZhang Mar 19, 2025
f22fa7d
style: 精简样式
ArgoZhang Mar 19, 2025
6e00c3d
refactor: 增加阴影效果
ArgoZhang Mar 19, 2025
b7c46bc
refactor: 移除 IsFixedSearch 参数
ArgoZhang Mar 19, 2025
929cd6d
test: 更新单元测试
ArgoZhang Mar 19, 2025
aa51deb
Merge branch 'main' into feat-virtualize
ArgoZhang Mar 19, 2025
419da1e
refactor: 移除 IsFixedSearch 参数
ArgoZhang Mar 19, 2025
af0778b
test: 更新单元测试
ArgoZhang Mar 19, 2025
b0b5b7a
doc: 更新默认值
ArgoZhang Mar 19, 2025
823e0af
refactor: 移除 IsFixedSearch 参数
ArgoZhang Mar 19, 2025
b38da7f
refactor: 标注已弃用
ArgoZhang Mar 19, 2025
2c1dd63
test: 更新单元测试
ArgoZhang Mar 19, 2025
65ff7ed
doc: 更新示例
ArgoZhang Mar 19, 2025
8a61f55
doc: 更新文档注释
ArgoZhang Mar 19, 2025
09eb49f
Merge branch 'main' into feat-virtualize
ArgoZhang Mar 19, 2025
6569ed7
doc: 增加示例
ArgoZhang Mar 19, 2025
22fbbc9
feat: 增加虚拟化功能
ArgoZhang Mar 19, 2025
fb6896c
refactor: 增加 CloseButtonIcon 图标参数
ArgoZhang Mar 19, 2025
474b46b
refactor: 更新图标
ArgoZhang Mar 19, 2025
3f0ee06
test: 更新单元测试
ArgoZhang Mar 19, 2025
6a9f450
Merge branch 'main' into feat-virtualize
ArgoZhang Mar 19, 2025
76e2180
refactor: 移除不使用的命名空间
ArgoZhang Mar 19, 2025
abb0d75
refactor: 微调搜索图标位置
ArgoZhang Mar 19, 2025
a238746
refactor: 增加虚拟化逻辑
ArgoZhang Mar 19, 2025
b1cb106
doc: 增加示例文档
ArgoZhang Mar 19, 2025
eaf638a
doc: 增加虚拟化参数文档
ArgoZhang Mar 19, 2025
3125b61
doc: 增加参数注释文档
ArgoZhang Mar 19, 2025
5e8a2eb
feat: 增加 IsClearable 支持
ArgoZhang Mar 19, 2025
6d46dfb
refactor: 增加样式
ArgoZhang Mar 19, 2025
fab60ed
doc: 更新示例
ArgoZhang Mar 19, 2025
f4dc3f8
test: 更新单元测试
ArgoZhang Mar 19, 2025
325231a
chore: bump version 9.5.0-beta06
ArgoZhang Mar 19, 2025
e49b173
test: 更新单元测试
ArgoZhang Mar 19, 2025
9a98a3c
doc: 移除 IsFixedSearch 相关文档
ArgoZhang Mar 20, 2025
26c8664
test: 更新单元测试
ArgoZhang Mar 20, 2025
a0682d0
chore: bump version 9.5.0-beta07
ArgoZhang Mar 20, 2025
373181f
Merge branch 'main' into feat-virtualize
ArgoZhang Mar 20, 2025
d6ead99
revert: 移除样式
ArgoZhang Mar 20, 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
71 changes: 70 additions & 1 deletion src/BootstrapBlazor.Server/Components/Samples/AutoFills.razor
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
<section ignore>
@((MarkupString)@Localizer["NormalDesc"].Value)
</section>
<AutoFill @bind-Value="Model1" Items="Items1" IsLikeMatch="true" OnGetDisplayText="OnGetDisplayText" class="mb-3" IsSelectAllTextOnFocus="true">
<AutoFill @bind-Value="Model1" Items="Items1" class="mb-3"
IsLikeMatch="true" OnGetDisplayText="OnGetDisplayText" IsSelectAllTextOnFocus="true">
<ItemTemplate>
<div class="d-flex">
<div>
Expand Down Expand Up @@ -71,4 +72,72 @@
</section>
</DemoBlock>

<DemoBlock Title="@Localizer["IsVirtualizeTitle"]" Introduction="@Localizer["IsVirtualizeIntro"]" Name="IsVirtualize">
<section ignore>
<p>@((MarkupString)Localizer["IsVirtualizeDescription"].Value)</p>
<div class="row g-3">
<div class="col-12 col-sm-6">
<BootstrapInputGroup>
<BootstrapInputGroupLabel DisplayText="IsClearable" />
<Checkbox @bind-Value="@_isClearable" />
</BootstrapInputGroup>
</div>
</div>
</section>

<p class="code-label">1. 使用 OnQueryAsync 作为数据源</p>
<div class="row mb-3">
<div class="col-12">
<AutoFill @bind-Value="Model4" OnQueryAsync="OnQueryAsync" OnGetDisplayText="OnGetDisplayText" class="mb-3"
IsSelectAllTextOnFocus="true" OnCustomFilter="OnCustomVirtulizeFilter"
IsVirtualize="true" RowHeight="58f" IsClearable="_isClearable">
<ItemTemplate>
<div class="d-flex">
<div>
<img src="@WebsiteOption.CurrentValue.GetAvatarUrl(context.Id)" class="bb-avatar" />
</div>
<div class="ps-2">
<div>@context.Name</div>
<div class="bb-sub">@Foo.GetTitle(context.Id)</div>
</div>
</div>
</ItemTemplate>
</AutoFill>
<section ignore>
@if (Model4 != null)
{
<EditorForm Model="@Model4" RowType="RowType.Inline" ItemsPerRow="2" />
}
</section>
</div>
</div>

<p class="code-label">2. 使用 Items 作为数据源</p>
<div class="row">
<div class="col-12">
<AutoFill @bind-Value="Model4" Items="Items4" OnGetDisplayText="OnGetDisplayText" class="mb-3"
IsSelectAllTextOnFocus="true" OnCustomFilter="OnCustomVirtulizeFilter"
IsVirtualize="true" RowHeight="58f" IsClearable="_isClearable">
<ItemTemplate>
<div class="d-flex">
<div>
<img src="@WebsiteOption.CurrentValue.GetAvatarUrl(context.Id)" class="bb-avatar" />
</div>
<div class="ps-2">
<div>@context.Name</div>
<div class="bb-sub">@Foo.GetTitle(context.Id)</div>
</div>
</div>
</ItemTemplate>
</AutoFill>
<section ignore>
@if (Model4 != null)
{
<EditorForm Model="@Model4" RowType="RowType.Inline" ItemsPerRow="2" />
}
</section>
</div>
</div>
</DemoBlock>

<AttributeTable Items="@GetAttributes()" />
41 changes: 41 additions & 0 deletions src/BootstrapBlazor.Server/Components/Samples/AutoFills.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@ partial class AutoFills

[NotNull]
private Foo Model2 { get; set; } = new();

[NotNull]
private Foo Model3 { get; set; } = new();

[NotNull]
private Foo Model4 { get; set; } = new();

private static string? OnGetDisplayText(Foo? foo) => foo?.Name;

[NotNull]
Expand All @@ -29,10 +33,15 @@ partial class AutoFills
[NotNull]
private IEnumerable<Foo>? Items3 { get; set; }

[NotNull]
private IEnumerable<Foo>? Items4 { get; set; }

[Inject]
[NotNull]
private IStringLocalizer<Foo>? LocalizerFoo { get; set; }

private bool _isClearable = true;

/// <inheritdoc/>
protected override void OnInitialized()
{
Expand All @@ -46,6 +55,9 @@ protected override void OnInitialized()

Items3 = Foo.GenerateFoo(LocalizerFoo);
Model3 = Items3.First();

Items4 = Foo.GenerateFoo(LocalizerFoo);
Model4 = Items3.First();
}

private Task<IEnumerable<Foo>> OnCustomFilter(string searchText)
Expand All @@ -54,6 +66,27 @@ private Task<IEnumerable<Foo>> OnCustomFilter(string searchText)
return Task.FromResult(items);
}

private Task<IEnumerable<Foo>> OnCustomVirtulizeFilter(string searchText)
{
var items = string.IsNullOrEmpty(searchText) ? Items4 : Items4.Where(i => i.Name!.Contains(searchText));
return Task.FromResult(items);
}

private async Task<QueryData<Foo>> OnQueryAsync(VirtualizeQueryOption option)
{
await Task.Delay(200);
var items = Foo.GenerateFoo(LocalizerFoo);
if (!string.IsNullOrEmpty(option.SearchText))
{
items = [.. items.Where(i => i.Name!.Contains(option.SearchText, StringComparison.OrdinalIgnoreCase))];
}
return new QueryData<Foo>
{
Items = items.Skip(option.StartIndex).Take(option.Count),
TotalCount = items.Count
};
}

/// <summary>
/// Get property method
/// </summary>
Expand Down Expand Up @@ -163,6 +196,14 @@ private AttributeItem[] GetAttributes() =>
Type = "bool",
ValueList = "true/false",
DefaultValue = "false"
},
new()
{
Name = nameof(AutoFill<string>.IsVirtualize),
Description = Localizer["AttrIsVirtualize"],
Type = "bool",
ValueList = "true/false",
DefaultValue = "false"
}
];
}
9 changes: 7 additions & 2 deletions src/BootstrapBlazor.Server/Locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -2151,7 +2151,11 @@
"Att10": "Whether to expand the dropdown candidate menu when it gains focus",
"Att11": "Candidate template",
"Att12": "Whether to skip Enter key handling",
"Att13": "Whether to skip Esc key processing"
"Att13": "Whether to skip Esc key processing",
"IsVirtualizeTitle": "Virtualize",
"IsVirtualizeIntro": "Set <code>IsVirtualize</code> to <b>true</b> enable virtual scroll for large data",
"IsVirtualizeDescription": "Component virtual scrolling supports two ways of providing data through <code>Items</code> or <code>OnQueryAsync</code> callback methods",
"AttrIsVirtualize": "Wether to enable virtualize"
},
"BootstrapBlazor.Server.Components.Samples.AutoCompletes": {
"Title": "AutoComplete",
Expand Down Expand Up @@ -3026,7 +3030,8 @@
"MultiSelectVirtualizeTitle": "Virtualize",
"MultiSelectVirtualizeIntro": "Set <code>IsVirtualize</code> to <b>true</b> enable virtual scroll for large data",
"MultiSelectVirtualizeDescription": "Component virtual scrolling supports two ways of providing data through <code>Items</code> or <code>OnQueryAsync</code> callback methods",
"MultiSelectsAttribute_ShowSearch": "Whether to display the search box"
"MultiSelectsAttribute_ShowSearch": "Whether to display the search box",
"MultiSelectsAttribute_IsVirtualize": "Wether to enable virtualize"
},
"BootstrapBlazor.Server.Components.Samples.Radios": {
"RadiosTitle": "Radio",
Expand Down
9 changes: 7 additions & 2 deletions src/BootstrapBlazor.Server/Locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -2151,7 +2151,11 @@
"Att10": "获得焦点时是否展开下拉候选菜单",
"Att11": "候选项模板",
"Att12": "是否跳过 Enter 按键处理",
"Att13": "是否跳过 Esc 按键处理"
"Att13": "是否跳过 Esc 按键处理",
"IsVirtualizeTitle": "虚拟滚动",
"IsVirtualizeIntro": "通过设置 <code>IsVirtualize</code> 参数开启组件虚拟功能特性",
"IsVirtualizeDescription": "组件虚拟滚动支持两种形式通过 <code>Items</code> 或者 <code>OnQueryAsync</code> 回调方法提供数据",
"AttrIsVirtualize": "是否开启虚拟滚动"
},
"BootstrapBlazor.Server.Components.Samples.AutoCompletes": {
"Title": "AutoComplete 自动完成",
Expand Down Expand Up @@ -3026,7 +3030,8 @@
"MultiSelectVirtualizeTitle": "虚拟滚动",
"MultiSelectVirtualizeIntro": "通过设置 <code>IsVirtualize</code> 参数开启组件虚拟功能特性",
"MultiSelectVirtualizeDescription": "组件虚拟滚动支持两种形式通过 <code>Items</code> 或者 <code>OnQueryAsync</code> 回调方法提供数据",
"MultiSelectsAttribute_ShowSearch": "是否显示搜索框"
"MultiSelectsAttribute_ShowSearch": "是否显示搜索框",
"MultiSelectsAttribute_IsVirtualize": "是否开启虚拟滚动"
},
"BootstrapBlazor.Server.Components.Samples.Radios": {
"RadiosTitle": "Radio 单选框",
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.5.0-beta05</Version>
<Version>9.5.0-beta07</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

@code {
RenderFragment RenderDropdown =>
@<ul class="dropdown-menu">
@<ul class="dropdown-menu shadow">
@foreach (var item in Rows)
{
<li @key="item" class="dropdown-item" @onclick="() => OnClickItem(item)">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
.auto-complete {
--bb-ac-padding-right: #{$bb-ac-padding-right};
--bb-ac-menu-top: #{$bb-ac-menu-top};
--bb-ac-menu-left: #{$bb-ac-menu-left};
--bb-ac-menu-right: #{$bb-ac-menu-right};
--bb-ac-menu-shadow: #{$bb-ac-menu-shadow};
--bb-ac-dropdown-max-height: var(--bb-dropdown-max-height);
--bb-select-append-width: #{$bb-select-append-width};
--bb-select-append-color: #{$bb-select-append-color};
position: relative;
Expand All @@ -15,11 +10,7 @@
}

.dropdown-menu {
top: var(--bb-ac-menu-top);
left: var(--bb-ac-menu-left);
right: var(--bb-ac-menu-right);
box-shadow: var(--bb-ac-menu-shadow);
max-height: var(--bb-ac-dropdown-max-height);
width: 100%;
}

.ac-loading {
Expand Down
50 changes: 43 additions & 7 deletions src/BootstrapBlazor/Components/AutoFill/AutoFill.razor
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@namespace BootstrapBlazor.Components
@using Microsoft.AspNetCore.Components.Web.Virtualization
@typeparam TValue
@inherits PopoverCompleteBase<TValue>

Expand All @@ -17,23 +18,58 @@
placeholder="@PlaceHolder" disabled="@Disabled" @ref="FocusElement" />
<span class="form-select-append"><i class="@Icon"></i></span>
<span class="form-select-append ac-loading"><i class="@LoadingIcon"></i></span>
@if (GetClearable())
{
<span class="@ClearClassString" @onclick="OnClearValue"><i class="@ClearIcon"></i></span>
}
<ul class="dropdown-menu">
@foreach (var item in Rows)
@if (IsVirtualize)
{
<li @key="@item" class="dropdown-item" @onclick="() => OnClickItem(item)">
@if (ItemTemplate != null)
<div class="dropdown-menu-body dropdown-virtual">
@if (OnQueryAsync == null)
{
@ItemTemplate(item)
<Virtualize ItemSize="RowHeight" OverscanCount="OverscanCount" Items="@Rows" ChildContent="RenderRow">
</Virtualize>
}
else
{
<div>@GetDisplayText(item)</div>
<Virtualize ItemSize="RowHeight" OverscanCount="OverscanCount" ItemsProvider="LoadItems"
Placeholder="RenderPlaceHolderRow" ItemContent="RenderRow" @ref="_virtualizeElement">
</Virtualize>
}
</li>
</div>
}
@if (ShowNoDataTip && Rows.Count == 0)
else if (ShowNoDataTip && Rows.Count == 0)
{
<li class="dropdown-item">@NoDataTip</li>
}
else
{
<div class="dropdown-menu-body">
@foreach (var item in Rows)
{
@RenderRow(item)
}
</div>
}
</ul>
</div>

@code {
RenderFragment<TValue> RenderRow => item =>
@<li @key="@item" class="dropdown-item" @onclick="() => OnClickItem(item)">
@if (ItemTemplate != null)
{
@ItemTemplate(item)
}
else
{
<div>@GetDisplayText(item)</div>
}
</li>;

RenderFragment<PlaceholderContext> RenderPlaceHolderRow => context =>
@<div class="dropdown-item">
<div class="is-ph"></div>
</div>;
}
Loading