ant-design-blazor/components/anchor/AnchorLink.razor.cs

166 lines
4.3 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using AntDesign.JsInterop;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using OneOf;
namespace AntDesign
{
[DebuggerDisplay("Href: {Href}")]
public partial class AnchorLink : AntDomComponentBase, IAnchor
{
private const string PrefixCls = "ant-anchor-link";
internal bool Active { get; private set; }
private bool _hrefDomExist;
private ClassMapper _titleClass = new ClassMapper();
private List<AnchorLink> _links = new List<AnchorLink>();
public DomRect LinkDom { get; private set; }
#region Parameters
[CascadingParameter(Name = "Root")]
public Anchor Root { get; set; }
private IAnchor _parent;
[CascadingParameter(Name = "Parent")]
public IAnchor Parent
{
get => _parent;
set
{
//Debug.WriteLine($"link:{Title} {GetHashCode()}\tparent:{value.GetHashCode()}");
_parent = value;
_parent?.Add(this);
}
}
[Parameter]
public RenderFragment ChildContent { get; set; }
/// <summary>
/// target of hyperlink
/// </summary>
[Parameter]
public string Href { get; set; }
/// <summary>
/// content of hyperlink
/// </summary>
[Parameter]
public string Title { get; set; }
/// <summary>
/// Specifies where to display the linked URL
/// </summary>
[Parameter]
public string Target { get; set; }
#endregion Parameters
internal string _hash = string.Empty;
protected override void Dispose(bool disposing)
{
_parent?.Remove(this);
base.Dispose(disposing);
}
protected override void OnInitialized()
{
base.OnInitialized();
ClassMapper.Clear()
.Add($"{PrefixCls}")
.If($"{PrefixCls}-active", () => Active);
_titleClass.Clear()
.Add($"{PrefixCls}-title")
.If($"{PrefixCls}-title-active", () => Active);
}
protected async override Task OnFirstAfterRenderAsync()
{
await base.OnFirstAfterRenderAsync();
feat(module: overlay): OverlayTrigger not bound to a div (#937) * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): OverlayTrigger not bound to a div * feat(module:overlay): Logic transfer to single Overlay * feat(module:overlay): remove obsolete duplication * feat(module:Tooltip): Add for unbounded oncontextmenu event handler * feat(module:tooltip): unbound js event listeners remove * docs(module:tooltip): unbound explanation * fix(module:button): attach Ref to top level html element @ref * feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div * docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation * feat(module:OverlayTrigger): common logic relocation * feat(module:overlaytrigger): Overlay not bound to a div * feat(module:DatePicker): Overlay not bound to a div * feat(module:select): Overlay not boud to div * fix(module:select): onclickarrow event relocation * fix(module:select): rename Show to OnArrowClick * feat(module:avatar): Overlay not bound to a div * docs(module:avatar): demo switch to unbound version * feat(module:autocomplete): partial OverlayTrigger not bound to a div * feat(module:slider): tooltip * docs(module:slider): tooltip * fix(module:overlay): add SetVisible method * feat: set Ref where missing, performance components register Ref when missing IsFixed flag for CascadeValue changed hard-code sequence numbers when using RenderTreeBuilder Rate component use Tooltip Unbound version Tabs test fix * fix: revert changes (accidental) * feat(module:upload): tooltip with unbound usage * feat(module:table): column use of unbound tooltip * feat(module:autocomplete):overlay unbound from div * fix(module:upload): missing div restore Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00
LinkDom = await JsInvokeAsync<DomRect>(JSInteropConstants.GetBoundingClientRect, Ref);
try
{
await JsInvokeAsync<DomRect>(JSInteropConstants.GetBoundingClientRect, "#" + Href.Split('#')[1]);
_hrefDomExist = true;
}
catch { }
}
public void Remove(AnchorLink anchorLink)
{
_links.Remove(anchorLink);
}
public void Add(AnchorLink anchorLink)
{
if (!_links.Where(l => !string.IsNullOrEmpty(l.Href))
.Select(l => l.Href)
.Contains(anchorLink.Href))
{
_links.Add(anchorLink);
}
}
public void Clear()
{
foreach (IAnchor link in _links)
{
link.Clear();
}
_links.Clear();
}
public List<AnchorLink> FlatChildren()
{
List<AnchorLink> results = new List<AnchorLink>();
if (!string.IsNullOrEmpty(Href))
{
_hash = Href.Contains('#') ? Href.Split('#')[1] : Href;
results.Add(this);
}
foreach (IAnchor child in _links)
{
results.AddRange(child.FlatChildren());
}
return results;
}
internal void Activate(bool active)
{
Active = active;
}
internal async Task<DomRect> GetHrefDom(bool forced = false)
{
DomRect domRect = null;
if (forced || _hrefDomExist)
{
domRect = await JsInvokeAsync<DomRect>(JSInteropConstants.GetBoundingClientRect, "#" + Href.Split('#')[1]);
}
return domRect;
}
private async void OnClick(MouseEventArgs args)
{
await Root.OnLinkClickAsync(args, this);
}
}
}