// 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
{
///
/// Start spying for scroll events for elements with the specified classes
///
/// the class name (without .) to identify the containers to spy on
///
public Task StartSpying(string elementsSelector);
///
/// Center the viewport to DOM element with the given Id
///
/// The Id of the DOM element, that should be centered
///
Task ScrollToSection(string id);
///
/// Center the viewport to the DOM element represented by the fragment inside the uri
///
/// The uri which contains the fragment. If no fragment it scrolls to the top of the page
///
Task ScrollToSection(Uri uri);
event EventHandler ScrollSectionSectionCentered;
///
/// Does the same as ScrollToSection but without the scrolling. This can be used to initially set an value
///
///
///
Task SetSectionAsActive(String id);
///
/// Get the current position of the centered section
///
string CenteredSection { get; }
}
public class ScrollSpy : IScrollSpy
{
public string CenteredSection { get; private set; }
private readonly IJSRuntime _js;
private DotNetObjectReference _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 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)
{
}
}
}
}