-
Notifications
You must be signed in to change notification settings - Fork 12
/
IntersectionObserve.cs
86 lines (64 loc) · 2.78 KB
/
IntersectionObserve.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using Blazor.IntersectionObserver.API;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Blazor.IntersectionObserver.Components
{
public class IntersectionObserve : ComponentBase, IAsyncDisposable
{
[Inject] private IIntersectionObserverService ObserverService { get; set; }
[Parameter] public RenderFragment<IntersectionObserverContext> ChildContent { get; set; }
[Parameter] public bool IsIntersecting { get; set; }
[Parameter] public EventCallback<bool> IsIntersectingChanged { get; set; }
[Parameter] public EventCallback<IntersectionObserverEntry> OnChange { get; set; }
[Parameter] public EventCallback OnDisposed { get; set; }
[Parameter] public IntersectionObserverOptions Options { get; set; }
[Parameter] public bool Once { get; set; }
public IntersectionObserverContext IntersectionObserverContext { get; set; } = new IntersectionObserverContext();
private IntersectionObserver Observer { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await this.InitialiseObserver();
}
}
private async Task InitialiseObserver()
{
if (this.IntersectionObserverContext?.Ref?.Current == null)
{
throw new Exception("You need to provide the element to observe, for example: @ref=\"Context.Ref.Current\"");
}
this.Observer = await this.ObserverService.Observe(this.IntersectionObserverContext.Ref.Current, this.OnIntersectUpdate, this.Options);
}
private async void OnIntersectUpdate(IList<IntersectionObserverEntry> entries)
{
var entry = entries?.FirstOrDefault();
if (entry == null) return;
await this.IsIntersectingChanged.InvokeAsync(entry.IsIntersecting);
await this.OnChange.InvokeAsync(entry);
this.IntersectionObserverContext.Entry = entry;
this.StateHasChanged();
if (this.Once && entry.IsIntersecting)
{
await this.Observer.Dispose();
this.Observer = null;
}
}
public async ValueTask DisposeAsync()
{
var observer = this.Observer;
if (observer == null) return;
this.Observer = null;
await observer.Dispose();
await this.OnDisposed.InvokeAsync();
}
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
this.ChildContent(this.IntersectionObserverContext)(builder);
}
}
}