Skip to content

Commit

Permalink
Merge pull request #23 from ljbc1994/feat/2.0.0
Browse files Browse the repository at this point in the history
feat(2.0.0): refactored to be in line with the api
  • Loading branch information
ljbc1994 authored May 19, 2021
2 parents 9f884fc + 550fe8f commit e9ca60d
Show file tree
Hide file tree
Showing 23 changed files with 556 additions and 616 deletions.
2 changes: 1 addition & 1 deletion LICENCE.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
(The MIT License)

Copyright (c) 2019 Louie Colgan
Copyright (c) 2021 Louie Colgan

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
Expand Down
59 changes: 47 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ object which contains the observer entry! Easy!
@using Blazor.IntersectionObserver
<IntersectionObserve>
<div>
Hey... look I'm @(context != null && context.IsIntersecting ? "in view": "out of view")
<div @ref="context.Ref.Current">
Hey... I'm @(context.IsIntersecting ? "in view": "out of view")
</div>
</IntersectionObserve>
```
Expand Down Expand Up @@ -179,14 +179,45 @@ To disconnect the observer, call `Disconnect` on the `IntersectionObserver` inst
observer.Disconnect();
```

This will remove all the observed elements from the observer, i.e.

```razor
@using Blazor.IntersectionObserver
@implements IAsyncDisposable
@inject IIntersectionObserverService ObserverService
<div @ref="ImageRef"></div>
@functions {
private IntersectionObserver Observer;
@* Code... *@
public async ValueTask DisconnectAll()
{
if (this.Observer != null)
{
await this.Observer.Disconnect();
}
}
}
```

#### `Dispose`
To remove the observer, call `Dispose` on the `IntersectionObserver` instance.

```cs
observer.Dispose();
```

This is a useful method to clean up observers when components are disposed of, i.e.

```razor
@using Blazor.IntersectionObserver
@implements IAsyncDisposable
@inject IIntersectionObserverService ObserverService
<div @ref="NicolasCageRef"></div>
<div @ref="ImageRef"></div>
@functions {
private IntersectionObserver Observer;
Expand All @@ -196,7 +227,7 @@ This is a useful method to clean up observers when components are disposed of, i
{
if (this.Observer != null)
{
await this.Observer.Disconnect();
await this.Observer.Dispose();
}
}
}
Expand All @@ -209,12 +240,14 @@ This is a useful method to clean up observers when components are disposed of, i

Rather than directly interfacing with the service, you can use this convenience component for quick and easy observing. You can access the observer entry through the implicit `@context`!

You need to make sure to provide the reference of the element you want to observe, this is done by passing the element reference to the context reference.

```razor
@* Injecting service... *@
<IntersectionObserve>
<div>
Hey... look I'm @(context != null && context.IsIntersecting ? "intersecting!": "not intersecting!")
<div @ref="context.Ref.Current">
Hey... look I'm @(context.IsIntersecting ? "intersecting!": "not intersecting!")
</div>
</IntersectionObserve>
Expand All @@ -227,13 +260,18 @@ Rather than directly interfacing with the service, you can use this convenience
- `IsIntersecting` (`bool`) - Whether the element is intersecting - used for two-way binding.
- `Options` (`IntersectionObserverOptions`) - The options for the observer.
- `Once` (`bool`) - Only observe once for an intersection, then the instance disposes of itself.
- `Style` (`string`) - The style for the element.
- `Class` (`string`) - The class for the element.

#### Context
The context is the `IntersectionObserverEntry` object, with the following signature:
The context is the `IntersectionObserverContext` object, with the following signature:

```cs
public class IntersectionObserverContext
{
public IntersectionObserverEntry Entry { get; set; }
public ForwardReference Ref { get; set; } = new ForwardReference();
public bool IsIntersecting => this.Entry?.IsIntersecting ?? false;
}

public class IntersectionObserverEntry
{
public bool IsIntersecting { get; set; }
Expand All @@ -250,9 +288,6 @@ public class IntersectionObserverEntry
}
```

## Implementation Detail
To avoid creating an unnecessary number of observers for every element being observed, if a `Blazor Observer` shares exactly the same options as another, they will both use the same `IntersectionObserver` instance in JS. As each `Blazor Observer` has a unique id and callback, the elements that are being observed will still be passed to their respective `Blazor Observer`.

## Feature Requests
There's so much that `IntersectionObserver` can do, so if you have any requests or you want better documentation and examples, feel free to make a pull request or create an issue!

Expand Down
10 changes: 7 additions & 3 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ pool:

variables:
buildConfiguration: 'Release'
variables:
Major: '2'
Minor: '0'
Patch: '0'

steps:
- task: UseDotNet@2
Expand Down Expand Up @@ -53,8 +57,8 @@ steps:
packagesToPack: 'src/Blazor.IntersectionObserver/*.csproj'
configuration: '$(buildConfiguration)'
versioningScheme: byPrereleaseNumber
majorVersion: '0'
minorVersion: '1'
patchVersion: '0'
majorVersion: '$(Major)'
minorVersion: '$(Minor)'
patchVersion: '$(Patch)'


8 changes: 5 additions & 3 deletions samples/Blazor.IntersectionObserver.Client/Pages/Index.razor
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
</div>

<div class="window">
<IntersectionObserve Options="@ObserverOptions" Class="box" Style="@BoxStyle" OnChange="@OnIntersectingChanged">
<div class="vertical">
Welcome to <strong>The Box!</strong>
<IntersectionObserve Options="@ObserverOptions" OnChange="@OnIntersectingChanged">
<div class="box" style="@BoxStyle" @ref="context.Ref.Current">
<div class="vertical">
Welcome to <strong>The Box!</strong>
</div>
</div>
</IntersectionObserve>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
<div class="card-columns">
@foreach (var image in Images)
{
<div class="card">
<IntersectionObserve Class="image-container" Once=@true>
@{var isIntersecting = (context != null && context.IsIntersecting);}
<div class="image-loader @(isIntersecting ? "image-loader--hide" : "image-loader--show")">Loading...</div>
<img class="image @(isIntersecting ? "image--show" : "image--hide")" src="@(isIntersecting ? image: "")" />
<div class="card" @key="image">
<IntersectionObserve Once=@true>
<div class="image-container" @ref="context.Ref.Current">
@{var isIntersecting = context.IsIntersecting;}
<div class="image-loader @(isIntersecting ? "image-loader--hide" : "image-loader--show")">Loading...</div>
<img class="image @(isIntersecting ? "image--show" : "image--hide")" src="@(isIntersecting ? image: "")" />
</div>
</IntersectionObserve>
<div class="card-body">
<h5 class="card-title">Card title</h5>
Expand All @@ -47,7 +49,7 @@
{
var height = RandomNumber(250, 650);
var width = RandomNumber(250, 650);
return $"https://www.placehold.it/{width}x{height}";
return $"https://picsum.photos/{width}/{height}?id=${x}";
})
.ToList();
}
Expand Down
4 changes: 2 additions & 2 deletions samples/Blazor.IntersectionObserver.Server/Pages/Index.razor
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
</div>

<div class="window">
<IntersectionObserve Options="@ObserverOptions" Class="box" Style="@BoxStyle" OnChange="@OnIntersectingChanged">
<div class="vertical">
<IntersectionObserve Options="@ObserverOptions" OnChange="@OnIntersectingChanged">
<div class="box" style="@BoxStyle" @ref="context.Ref.Current">
Welcome to <strong>The Box!</strong>
</div>
</IntersectionObserve>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
<div class="card-columns">
@foreach (var image in Images)
{
<div class="card">
<IntersectionObserve Class="image-container" Once=@true>
@{var isIntersecting = (context != null && context.IsIntersecting);}
<div class="image-loader @(isIntersecting ? "image-loader--hide" : "image-loader--show")">Loading...</div>
<img class="image @(isIntersecting ? "image--show" : "image--hide")" src="@(isIntersecting ? image: "")" />
<div class="card" @key="image">
<IntersectionObserve Once=@true>
<div class="image-container" @ref="context.Ref.Current">
@{var isIntersecting = context.IsIntersecting;}
<div class="image-loader @(isIntersecting ? "image-loader--hide" : "image-loader--show")">Loading...</div>
<img class="image @(isIntersecting ? "image--show" : "image--hide")" src="@(isIntersecting ? image: "")" />
</div>
</IntersectionObserve>
<div class="card-body">
<h5 class="card-title">Card title</h5>
Expand All @@ -47,7 +49,7 @@
{
var height = RandomNumber(250, 650);
var width = RandomNumber(250, 650);
return $"https://www.placehold.it/{width}x{height}";
return $"https://picsum.photos/{width}/{height}?id={x}";
})
.ToList();
}
Expand Down
20 changes: 20 additions & 0 deletions src/Blazor.IntersectionObserver/API/ForwardReference.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Components;

namespace Blazor.IntersectionObserver.API
{
public class ForwardReference
{
private ElementReference current;

public ElementReference Current
{
get => this.current;
set => this.Set(value);
}

public void Set(ElementReference value)
{
this.current = value;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,17 @@
<Title>Blazor Intersection Observer</Title>
<Description>Intersection Observer API for Blazor applications</Description>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>1.1.0</Version>
<Version>2.0.0</Version>
<Product>BlazorIntersectionObserver</Product>
<PackageReleaseNotes>06/12/2020
<PackageReleaseNotes>
19/05/2021
- *BREAKING CHANGE* The IntersectionObserve component now requires a reference to the node it's observing.
- The imported observer script is now minified.

06/12/2020
- Updated project to use dotnet 5</PackageReleaseNotes>
<PackageLicenseFile>LICENCE.txt</PackageLicenseFile>
<Copyright>Copyright © 2021 - Louie Colgan</Copyright>
</PropertyGroup>

<ItemGroup>
Expand Down
12 changes: 7 additions & 5 deletions src/Blazor.IntersectionObserver/Configuration/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ namespace Blazor.IntersectionObserver.Configuration
{
internal static class Constants
{
public static string CREATE = $"create";
public static string CREATE = "create";

public static string OBSERVE = $"observe";
public static string OBSERVE = "observe";

public static string UNOBSERVE = $"unobserve";
public static string UNOBSERVE = "unobserve";

public static string DISCONNECT = $"disconnect";
public static string DISCONNECT = "disconnect";

public static string OBSERVE_ELEMENT = $"observeElement";
public static string OBSERVE_ELEMENT = "observeElement";

public static string REMOVE = "remove";
}
}
Original file line number Diff line number Diff line change
@@ -1,35 +1,32 @@
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 IntersectionObserveBase : ComponentBase, IAsyncDisposable
public class IntersectionObserve : ComponentBase, IAsyncDisposable
{
[Inject] private IIntersectionObserverService ObserverService { get; set; }

[Parameter] public string Class { get; set; }

[Parameter] public string Style { get; set; }

[Parameter] public RenderFragment<IntersectionObserverEntry> ChildContent { 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 ElementReference Element { get; set; }

public IntersectionObserverEntry Entry { get; set; }
public IntersectionObserverContext IntersectionObserverContext { get; set; } = new IntersectionObserverContext();

private IntersectionObserver Observer { get; set; }

Expand All @@ -43,7 +40,12 @@ protected override async Task OnAfterRenderAsync(bool firstRender)

private async Task InitialiseObserver()
{
this.Observer = await this.ObserverService.Observe(this.Element, this.OnIntersectUpdate, this.Options);
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)
Expand All @@ -55,22 +57,30 @@ private async void OnIntersectUpdate(IList<IntersectionObserverEntry> entries)
await this.IsIntersectingChanged.InvokeAsync(entry.IsIntersecting);
await this.OnChange.InvokeAsync(entry);

this.Entry = entry;
this.IntersectionObserverContext.Entry = entry;
this.StateHasChanged();

if (this.Once && entry.IsIntersecting)
{
await this.Observer.Disconnect();
await this.Observer.Dispose();
this.Observer = null;
}
}

public async ValueTask DisposeAsync()
{
if (this.Observer != null)
{
await this.Observer.Disconnect();
}
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);
}
}
}
5 changes: 0 additions & 5 deletions src/Blazor.IntersectionObserver/IntersectionObserve.razor

This file was deleted.

Loading

0 comments on commit e9ca60d

Please sign in to comment.