ant-design-blazor/components/anchor/AnchorLink.razor.cs
Brian Ding 8c8a2e3a79 feat: add anchor component (#281)
* feat(module: anchor): add component anchor

* feat(module: anchor): add component anchor

* feat(module: anchor): implement OnScroll

* feat(module: anchor): activate anchorlink

* feat(module: anchor): implement basic demo

* feat(module: anchor): implement static demo

* feat(module: anchor): add OnClick & OnChange

* feat(module: anchor): implement demos

* feat(module: anchor): move IAnchor to folder anchor

* fix: click hash link

* feat(module: anchor): improve cascading value & fix active anchor highlight

* feat(module: anchor): cascading root/parent

* fix(module: anchor): highlight active anchor link

* fix: remove duplicated cascading value

Co-authored-by: ElderJames <shunjiey@hotmail.com>
2020-06-30 22:03:31 +08:00

140 lines
3.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AntDesign.JsInterop;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using OneOf;
namespace AntDesign
{
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 ElementReference _self;
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 OnInitialized()
{
base.OnInitialized();
ClassMapper.Clear()
.Add($"{PrefixCls}")
.If($"{PrefixCls}-active", () => Active);
_titleClass.Clear()
.Add($"{PrefixCls}-title")
.If($"{PrefixCls}-title-active", () => Active);
_hash = Href.Split('#')[1];
}
protected async override Task OnFirstAfterRenderAsync()
{
await base.OnFirstAfterRenderAsync();
LinkDom = await JsInvokeAsync<DomRect>(JSInteropConstants.getBoundingClientRect, _self);
try
{
await JsInvokeAsync<DomRect>(JSInteropConstants.getBoundingClientRect, "#" + Href.Split('#')[1]);
_hrefDomExist = true;
}
catch { }
}
public void Add(AnchorLink anchorLink)
{
_links.Add(anchorLink);
}
public List<AnchorLink> FlatChildren()
{
List<AnchorLink> results = new List<AnchorLink>();
if (!string.IsNullOrEmpty(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);
}
}
}