ant-design-blazor/components/anchor/AnchorLink.razor.cs
Andrzej Bakun 152a574577 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

166 lines
4.3 KiB
C#

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();
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);
}
}
}