You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
113 lines
3.7 KiB
113 lines
3.7 KiB
// Copyright (c) MudBlazor 2021
|
|
// MudBlazor licenses this file to you under the MIT license.
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
using System;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.JSInterop;
|
|
|
|
namespace Connected
|
|
{
|
|
public class ScrollSectionCenteredEventArgs
|
|
{
|
|
public ScrollSectionCenteredEventArgs(string id)
|
|
{
|
|
Id = id;
|
|
}
|
|
|
|
public string Id { get; init; }
|
|
}
|
|
|
|
public interface IScrollSpy : IAsyncDisposable
|
|
{
|
|
/// <summary>
|
|
/// Start spying for scroll events for elements with the specified classes
|
|
/// </summary>
|
|
/// <param name="elementsSelector">the class name (without .) to identify the containers to spy on</param>
|
|
/// <returns></returns>
|
|
public Task StartSpying(string elementsSelector);
|
|
|
|
/// <summary>
|
|
/// Center the viewport to DOM element with the given Id
|
|
/// </summary>
|
|
/// <param name="id">The Id of the DOM element, that should be centered</param>
|
|
/// <returns></returns>
|
|
Task ScrollToSection(string id);
|
|
|
|
/// <summary>
|
|
/// Center the viewport to the DOM element represented by the fragment inside the uri
|
|
/// </summary>
|
|
/// <param name="uri">The uri which contains the fragment. If no fragment it scrolls to the top of the page</param>
|
|
/// <returns></returns>
|
|
Task ScrollToSection(Uri uri);
|
|
event EventHandler<ScrollSectionCenteredEventArgs> ScrollSectionSectionCentered;
|
|
|
|
/// <summary>
|
|
/// Does the same as ScrollToSection but without the scrolling. This can be used to initially set an value
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
Task SetSectionAsActive(String id);
|
|
|
|
/// <summary>
|
|
/// Get the current position of the centered section
|
|
/// </summary>
|
|
string CenteredSection { get; }
|
|
}
|
|
|
|
public class ScrollSpy : IScrollSpy
|
|
{
|
|
public string CenteredSection { get; private set; }
|
|
private readonly IJSRuntime _js;
|
|
private DotNetObjectReference<ScrollSpy> _dotNetRef;
|
|
|
|
[DynamicDependency(nameof(SectionChangeOccured))]
|
|
public ScrollSpy(IJSRuntime js)
|
|
{
|
|
_js = js;
|
|
_dotNetRef = DotNetObjectReference.Create(this);
|
|
}
|
|
|
|
public async Task StartSpying(string containerSelector) => await _js.InvokeVoidAsync
|
|
("mudScrollSpy.spying", containerSelector, _dotNetRef);
|
|
|
|
[JSInvokable]
|
|
public void SectionChangeOccured(string id)
|
|
{
|
|
CenteredSection = id;
|
|
ScrollSectionSectionCentered?.Invoke(this, new ScrollSectionCenteredEventArgs(id));
|
|
}
|
|
|
|
public event EventHandler<ScrollSectionCenteredEventArgs> ScrollSectionSectionCentered;
|
|
|
|
public async Task ScrollToSection(string id)
|
|
{
|
|
CenteredSection = id;
|
|
await _js.InvokeVoidAsyncWithErrorHandling
|
|
("mudScrollSpy.scrollToSection", id.Trim('#'));
|
|
}
|
|
|
|
public async Task SetSectionAsActive(string id)
|
|
{
|
|
CenteredSection = id;
|
|
await _js.InvokeVoidAsyncWithErrorHandling
|
|
("mudScrollSpy.activateSection", id.Trim('#'));
|
|
}
|
|
|
|
public async Task ScrollToSection(Uri uri) => await ScrollToSection(uri.Fragment);
|
|
|
|
public async ValueTask DisposeAsync()
|
|
{
|
|
try
|
|
{
|
|
_dotNetRef?.Dispose();
|
|
await _js.InvokeVoidAsyncWithErrorHandling("mudScrollSpy.unspy");
|
|
}
|
|
catch (Exception)
|
|
{
|
|
}
|
|
}
|
|
}
|
|
}
|