ant-design-blazor/components/dropdown/DropdownButton.cs

237 lines
7.0 KiB
C#
Raw Normal View History

using System;
using System.Text.Json;
using System.Threading.Tasks;
using AntDesign.JsInterop;
using Microsoft.AspNetCore.Components;
using OneOf;
namespace AntDesign
{
public class DropdownButton : Dropdown
{
/// <summary>
/// Option to fit button width to its parent width
/// </summary>
[Parameter]
public new bool Block
{
get => base.Block;
set => base.Block = value;
}
/// <summary>
/// Fully customizable button.
/// </summary>
[Parameter]
public new Func<RenderFragment, RenderFragment, RenderFragment> ButtonsRender
{
get => base.ButtonsRender;
set => base.ButtonsRender = value;
}
/// <summary>
/// Allows to set each button's css class either to the same string
/// or separately.
/// </summary>
[Parameter]
public OneOf<string, (string LeftButton, string RightButton)> ButtonsClass
{
get =>_buttonsClass;
set
{
_buttonsClass = value;
_buttonsClass.Switch(
single =>
{
ChangeButtonClass(single, single);
},
both =>
{
ChangeButtonClass(both.LeftButton, both.RightButton);
});
}
}
/// <summary>
/// Allows to set each button's style either to the same string
/// or separately.
/// </summary>
[Parameter]
public OneOf<string, (string LeftButton, string RightButton)> ButtonsStyle
{
get => _buttonsStyle;
set
{
_buttonsStyle = value;
_buttonsStyle.Switch(
single =>
{
ChangeButtonStyles(single, single);
},
both =>
{
ChangeButtonStyles(both.LeftButton, both.RightButton);
});
}
}
/// <summary>
/// Set the danger status of button
/// </summary>
[Parameter]
public bool Danger
{
get => _danger;
set
{
_danger = value;
ChangeButtonDanger(value);
}
}
/// <summary>
/// Used in situations with complex background, home pages usually.
/// </summary>
[Parameter]
public bool Ghost
{
get => _ghost;
set
{
_ghost = value;
ChangeButtonGhost(value);
}
}
private string _icon = "ellipsis";
/// <summary>
/// Icon that will be rendered in the right
/// button.
/// </summary>
[Parameter]
public string Icon
{
get => _icon;
set
{
_icon = value;
ChangeRightButtonIcon(value);
}
}
/// <summary>
/// Indicates if loading icon is going to be included.
/// If set to true, then dropdown will not be active.
/// </summary>
[Parameter]
public bool Loading
{
get => _loading;
set
{
_loading = value;
ChangeButtonLoading(value);
}
}
private string _size = AntSizeLDSType.Default;
/// <summary>
/// Button size.
/// </summary>
[Parameter]
public string Size
{
get => _size;
set
{
_size = value;
ChangeButtonSize(value);
}
}
/// <summary>
/// Allows to set each button's type either to the same string
/// or separately. Use AntDesign.ButtonType helper class.
/// </summary>
[Parameter]
public OneOf<string, (string LeftButton, string RightButton)> Type
{
get => _buttonsType;
set
{
_buttonsType = value;
_buttonsType.Switch(
single =>
{
ChangeButtonType(single, single);
},
both =>
{
ChangeButtonType(both.LeftButton, both.RightButton);
});
}
}
private bool _loading;
private bool _danger;
private bool _ghost = false;
private OneOf<string, (string LeftButton, string RightButton)> _buttonsStyle;
private OneOf<string, (string LeftButton, string RightButton)> _buttonsClass;
private OneOf<string, (string LeftButton, string RightButton)> _buttonsType = ButtonType.Default;
public DropdownButton() => IsButton = true;
protected override void OnInitialized()
{
string prefixCls = "ant-btn";
ClassMapper.Clear();
Placement = PlacementType.BottomRight;
base.OnInitialized();
ClassMapper.If($"{prefixCls}-block", () => Block);
}
/// <summary>
/// Force overlay trigger to be attached to wrapping element of
/// the right button. Right button has to be wrapped,
/// because overlay will be looking for first child
/// element of the overlay trigger to calculate the overlay position.
/// If the right button was the trigger, then its first child
/// would be the icon/ellipsis and the overlay would have been
/// rendered too high.
/// </summary>
/// <param name="firstRender"></param>
/// <returns></returns>
protected override Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
Ref = RefBack.Current;
perf: avoid memory leak issue of event listener (#1857) * perf: avoid memory leak #1834 Avoid memory leak by remove the exclusive parameter and logic in the code block on AddEventListener method in DomEventService class. The following are the components affected: components/affix/Affix.razor.cs components/anchor/Anchor.razor.cs components/carousel/Carousel.razor.cs components/core/Component/Overlay/Overlay.razor.cs components/core/Component/Overlay/OverlayTrigger.razor.cs components/core/JsInterop/DomEventService.cs components/descriptions/Descriptions.razor.cs components/dropdown/DropdownButton.cs components/grid/Row.razor.cs components/input/Input.cs components/input/TextArea.razor.cs components/layout/Sider.razor.cs components/list/ListItem.razor.cs components/select/Select.razor.cs components/select/internal/SelectContent.razor.cs components/slider/Slider.razor.cs components/table/Table.razor.cs components/tabs/Tabs.razor.cs * fix override AddEventListener method in AntDesign.TestKit project * add register/remove event listerner for exclusive use in DomEventService class * move _dotNetObjects to DomEventListerner class/service, so that users not required to maintain it in each component. * * move share/reuse dom event listerner methods to DomEventListerner class * remove method 'AddEventListener' that no longer exists in DomEventService class in AntDesign.TestKit project * * change the component referring to an IDomEventListerner interface instead of a concrete class, so that the component can be tested via a mock TestDomEventListerner. * introduce DisposeShared and Dispose method in DomEventListerner to ease user remove callback from DomEventListerner * register IDomEventListerner into DI container instead of create manually * fix FormatKey * fix FormatKey * fix tests * fix test * fix test Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-09-09 12:56:11 +08:00
DomEventListener.AddExclusive<JsonElement>(Ref, "click", OnUnboundClick);
DomEventListener.AddExclusive<JsonElement>(Ref, "mouseover", OnUnboundMouseEnter);
DomEventListener.AddExclusive<JsonElement>(Ref, "mouseout", OnUnboundMouseLeave);
DomEventListener.AddExclusive<JsonElement>(Ref, "focusin", OnUnboundFocusIn);
DomEventListener.AddExclusive<JsonElement>(Ref, "focusout", OnUnboundFocusOut);
DomEventListener.AddExclusive<JsonElement>(Ref, "contextmenu", OnContextMenu, true);
}
return base.OnAfterRenderAsync(firstRender);
}
protected override void Dispose(bool disposing)
{
perf: avoid memory leak issue of event listener (#1857) * perf: avoid memory leak #1834 Avoid memory leak by remove the exclusive parameter and logic in the code block on AddEventListener method in DomEventService class. The following are the components affected: components/affix/Affix.razor.cs components/anchor/Anchor.razor.cs components/carousel/Carousel.razor.cs components/core/Component/Overlay/Overlay.razor.cs components/core/Component/Overlay/OverlayTrigger.razor.cs components/core/JsInterop/DomEventService.cs components/descriptions/Descriptions.razor.cs components/dropdown/DropdownButton.cs components/grid/Row.razor.cs components/input/Input.cs components/input/TextArea.razor.cs components/layout/Sider.razor.cs components/list/ListItem.razor.cs components/select/Select.razor.cs components/select/internal/SelectContent.razor.cs components/slider/Slider.razor.cs components/table/Table.razor.cs components/tabs/Tabs.razor.cs * fix override AddEventListener method in AntDesign.TestKit project * add register/remove event listerner for exclusive use in DomEventService class * move _dotNetObjects to DomEventListerner class/service, so that users not required to maintain it in each component. * * move share/reuse dom event listerner methods to DomEventListerner class * remove method 'AddEventListener' that no longer exists in DomEventService class in AntDesign.TestKit project * * change the component referring to an IDomEventListerner interface instead of a concrete class, so that the component can be tested via a mock TestDomEventListerner. * introduce DisposeShared and Dispose method in DomEventListerner to ease user remove callback from DomEventListerner * register IDomEventListerner into DI container instead of create manually * fix FormatKey * fix FormatKey * fix tests * fix test * fix test Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-09-09 12:56:11 +08:00
DomEventListener.DisposeExclusive();
base.Dispose(disposing);
}
internal override async Task Show(int? overlayLeft = null, int? overlayTop = null)
{
if (!Loading)
{
await _overlay.Show(overlayLeft, overlayTop);
}
}
}
}