fix(module: select): DropdownRender doesn't pass original content into renderfargment (#3675)

* fix(module: select): dropdown render doesn't pass original content into renderfargment

* fix select box width

* fix aria-label
This commit is contained in:
James Yeung 2024-02-08 12:58:16 +08:00 committed by GitHub
parent ae67bcb448
commit 1b8a9c3a93
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 169 additions and 105 deletions

View File

@ -21,81 +21,13 @@
OverlayLeaveCls="ant-slide-up-leave ant-slide-up-leave-active ant-slide-up">
<Overlay>
<div style="@_dropdownStyle">
@if (SelectOptions != null)
{
<div class="" style="max-height: @PopupContainerMaxHeight; overflow-y: auto;" @ref="_scrollableSelectDiv">
<div>
<div class="" role="listbox" style="@ListboxStyle">
@if (CustomTagSelectOptionItem != null)
{
<CascadingValue Value="@ItemTemplate" Name="ItemTemplate">
<CascadingValue Value="@CustomTagSelectOptionItem" Name="Model">
<SelectOption
@key="@CustomTagSelectOptionItem.InternalId"
TItemValue="TItemValue"
TItem="TItem">
</SelectOption>
</CascadingValue>
</CascadingValue>
}
@SelectOptions
@if (AddedTags != null)
{
foreach (var selectOption in AddedTags)
{
<CascadingValue Value="@ItemTemplate" Name="ItemTemplate">
<CascadingValue Value="@selectOption" Name="Model">
<SelectOption
@key="@selectOption.InternalId"
TItemValue="TItemValue"
TItem="TItem">
</SelectOption>
</CascadingValue>
</CascadingValue>
}
}
</div>
</div>
</div>
}
else if (SelectOptions == null && !AllOptionsHidden())
{
<div class="" style="max-height: @PopupContainerMaxHeight; overflow-y: auto;" @ref="_scrollableSelectDiv">
<div>
<div class="" role="listbox" style="@ListboxStyle">
@{
@if (!IsGroupingEnabled)
{
@selectOptionsRender((this, ItemTemplate))
}
else
{
<CascadingValue Value="@ItemTemplate" Name="ItemTemplate">
<SelectOptionGroup TItemValue="TItemValue" TItem="TItem"></SelectOptionGroup>
</CascadingValue>
}
}
</div>
</div>
</div>
}
@if (AllOptionsHidden())
{
<div role="listbox" id="@(Id)_list" class="@ClassPrefix-item-empty">
@if (NotFoundContent != null)
{
@NotFoundContent
}
else
{
<Empty Simple Small/>
}
</div>
}
@if (DropdownRender != null)
{
@DropdownRender(default)
@DropdownRender(RenderOptionDropdown())
}
else
{
@RenderOptionDropdown()
}
</div>
</Overlay>
@ -164,4 +96,82 @@
</SelectOption>
</CascadingValue>
</CascadingValue>;
RenderFragment RenderOptionDropdown()
{
@if (SelectOptions != null)
{
return @<div class="" style="max-height: @PopupContainerMaxHeight; overflow-y: auto;" @ref="_scrollableSelectDiv">
<div>
<div class="" role="listbox" style="@ListboxStyle">
@if (CustomTagSelectOptionItem != null)
{
<CascadingValue Value="@ItemTemplate" Name="ItemTemplate">
<CascadingValue Value="@CustomTagSelectOptionItem" Name="Model">
<SelectOption @key="@CustomTagSelectOptionItem.InternalId"
TItemValue="TItemValue"
TItem="TItem">
</SelectOption>
</CascadingValue>
</CascadingValue>
}
@SelectOptions
@if (AddedTags != null)
{
foreach (var selectOption in AddedTags)
{
<CascadingValue Value="@ItemTemplate" Name="ItemTemplate">
<CascadingValue Value="@selectOption" Name="Model">
<SelectOption @key="@selectOption.InternalId"
TItemValue="TItemValue"
TItem="TItem">
</SelectOption>
</CascadingValue>
</CascadingValue>
}
}
</div>
</div>
</div>
;
}
else if (SelectOptions == null && !AllOptionsHidden())
{
return@<div class="" style="max-height: @PopupContainerMaxHeight; overflow-y: auto;" @ref="_scrollableSelectDiv">
<div>
<div class="" role="listbox" style="@ListboxStyle">
@{
@if (!IsGroupingEnabled)
{
@selectOptionsRender((this, ItemTemplate))
}
else
{
<CascadingValue Value="@ItemTemplate" Name="ItemTemplate">
<SelectOptionGroup TItemValue="TItemValue" TItem="TItem"></SelectOptionGroup>
</CascadingValue>
}
}
</div>
</div>
</div>;
}
@if (AllOptionsHidden())
{
return@<div role="listbox" id="@(Id)_list" class="@ClassPrefix-item-empty">
@if (NotFoundContent != null)
{
@NotFoundContent
}
else
{
<Empty Simple Small />
}
</div>
;
}
return builder => { };
}
}

View File

@ -137,9 +137,9 @@ namespace AntDesign
[Parameter] public string DropdownMaxWidth { get; set; } = "auto";
/// <summary>
/// Customize dropdown content.
/// Customize dropdown content. The context is the original content.
/// </summary>
[Parameter] public Func<RenderFragment, RenderFragment> DropdownRender { get; set; }
[Parameter] public RenderFragment<RenderFragment> DropdownRender { get; set; }
/// <summary>
/// The name of the property to be used as a group indicator.
@ -328,6 +328,7 @@ namespace AntDesign
/// Specifies predicate for disabled options
/// </summary>
[Parameter] public Func<TItem, bool> DisabledPredicate { get => _getDisabled; set => _getDisabled = value; }
/// <summary>
/// Used when Mode = default - The value is used during initialization and when pressing the Reset button within Forms.
/// </summary>

View File

@ -8,7 +8,7 @@
class="@ClassMapper.Class"
role="option"
aria-selected="@IsSelected"
aria-label="@(ItemTemplate != null ? ItemTemplate(Model.Item) : InternalLabel)"
aria-label="@InternalLabel"
style="@InnerStyle"
@onclick="@OnClick"
@onmouseenter="@OnMouseEnter">

View File

@ -6,10 +6,23 @@
LabelName="@nameof(Person.Name)"
Placeholder="custom dropdown render"
OnSelectedItemChanged="OnSelectedItemChangedHandler"
Style="width: 240px;"
DropdownRender="@DropdownRender">
Style="width: 240px;">
<DropdownRender Context="originNode">
<div>
@originNode
<Divider Style="margin: 4px 0"></Divider>
<div style="display: flex; flex-wrap: nowrap; padding: 8px">
<Input Style="flex: auto" @bind-Value="@_name" />
<a style="flex: none; padding: 8px; display: block; cursor: pointer" @onclick="AddItem">
<Icon Type="plus" Theme="outline"></Icon>
Add Item
</a>
</div>
</div>
</DropdownRender>
</Select>
<br /><br />
<br />
<br />
<p>
Selected Value: @_selectedValue <br />
Selected Item Name: @_selectedItem?.Name
@ -33,7 +46,7 @@
_list = new List<Person>
{
new Person {Id = 1, Name = "Jack"},
new Person {Id = 2, Name = "Lucy"}
new Person {Id = 2, Name = "Lucy"}
};
}
@ -42,33 +55,13 @@
_selectedItem = value;
}
private RenderFragment DropdownRender(RenderFragment originNode)
{
RenderFragment customDropdownRender =
@<Template>
<div>
@originNode
<Divider Style="margin: 4px 0"></Divider>
<div style="display: flex; flex-wrap: nowrap; padding: 8px">
<Input Style="flex: auto" @bind-Value="@_name"/>
<a style="flex: none; padding: 8px; display: block; cursor: pointer" @onclick="AddItem">
<Icon Type="plus" Theme="outline"></Icon>
Add Item
</a>
</div>
</div>
</Template>;
return customDropdownRender;
}
private void AddItem(MouseEventArgs args)
{
if (!string.IsNullOrWhiteSpace(_name))
{
if (!string.IsNullOrWhiteSpace(_name))
{
int newId = _list.Count() + 1;
_list.Add(new Person {Id = newId, Name = _name});
_name = string.Empty;
}
_list.Add(new Person { Id = newId, Name = _name });
_name = string.Empty;
}
}
}

View File

@ -0,0 +1,42 @@
@using AntDesign.Docs.Services
<Select Style="width: 200px;"
ValueProperty="c=>c"
LabelProperty="c=>c"
DataSource="_currentNames"
DropdownMatchSelectWidth="false"
ListboxStyle="display:flex;height: 200px;flex-flow: wrap; max-width: 500px; align-content: baseline;">
<ItemTemplate>
<Icon Type="@context" />
</ItemTemplate>
<LabelTemplate>
<p style="line-height: 30px;"><Icon Type="@context" /> @context</p>
</LabelTemplate>
<DropdownRender>
<Tabs OnChange="OnChange">
@foreach(var item in _lstIcons)
{
<TabPane Key="@item.Key" Tab="@item.Key"> </TabPane>
}
</Tabs>
@context
</DropdownRender>
</Select>
@inject IconListService _iconListService
@code
{
private Dictionary<string, List<string>> _lstIcons;
private List<string> _currentNames;
protected override void OnInitialized()
{
_lstIcons = _iconListService.GetIcons().ToDictionary(x => x.Category, x => x.IconNames);
base.OnInitialized();
}
private void OnChange(string tab)
{
_currentNames = _lstIcons[tab];
}
}

View File

@ -0,0 +1,18 @@
---
order: 23
title:
zh-CN: 自定义下拉框样式
en-US: Custom listbox style
---
## zh-CN
下拉框默认是列表样式,可利用 `ListboxStyle` 属性自定义样式。
本示例为图标选择器。
## en-US
The drop-down box defaults to a list style and can be customized with `ListboxStyle`.
This example is an icon selector.