GithubHelp home page GithubHelp logo

kristofferstrube / blazor.popper Goto Github PK

View Code? Open in Web Editor NEW
25.0 2.0 4.0 8.6 MB

A Blazor wrapper for the Javascript library Popper.js

License: MIT License

C# 58.95% JavaScript 9.24% HTML 31.81%
tooltip blazor javascript align blazor-wrapper blazor-webassembly popper

blazor.popper's Introduction

License: MIT GitHub issues GitHub forks GitHub stars NuGet Downloads (official NuGet)

Introduction

A Blazor wrapper for the JavaScript library Popper.js

Demo

The sample project can be demoed at https://kristofferstrube.github.io/Blazor.Popper/

Getting Started

Prerequisites

You need to install .NET 6.0 or newer to use the library.

Download .NET 6

Installation

You can install the package via Nuget with the Package Manager in your IDE or alternatively using the command line:

dotnet add package KristofferStrube.Blazor.Popper

Usage

The package can be used in Blazor WebAssembly projects.

Assets

You first need to reference popper.js since this is only a wrapper. You can do this using your favorite JS package manager (e.g. NPM or Library Manager) or just add the following to the body of your index.html file after the point where you reference _framework/blazor.webassembly.js.

<script src="https://unpkg.com/@popperjs/core@2"></script>

Import

You also need to reference the package in order to use it in your pages. This can be done in _Import.razor by adding the following.

@using KristofferStrube.Blazor.Popper

Add to service collection

An easy way to make Popper available in all your pages is by registering it in the IServiceCollection so that it can be dependency injected in the pages that need it. This is done in Program.cs by adding the following before you build the service collection.

public static async Task Main(string[] args)
{
    var builder = WebAssemblyHostBuilder.CreateDefault(args);
    builder.RootComponents.Add<App>("#app");

    // Other services are added.

    builder.Services.AddScoped<Popper>();

    await builder.Build().RunAsync();
}

Inject in page

In any page that need a popper you can then inject Popper by adding the following to the top of the razor file.

@inject Popper Popper;

Then you can use Popper to create a popper instance between two ElementReference's like so:

<span @ref=reference>reference</span>
<span @ref=popper>popper</span>

@code {
    protected ElementReference reference;
    protected ElementReference popper;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await Popper.CreatePopperAsync(reference, popper, new());
    }
}

Related articles

This repository was build on top of the work done in the following series of articles:

blazor.popper's People

Contributors

kristofferstrube avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

blazor.popper's Issues

How to invoke popper for target in a foreach loop

Hi Kristoffer,

I was just about to write a popper interop and found yours. Thanks for a good work!.

Would you be so kind and provide a sample on how to invoke popper for a reference in a foreach loop?

foreach(var item in Items)
{
   <button type="button" id="reference" @ref=??? aria-describedby="tooltip"
                  @onclick="_ => new Popper(???, tooltip)">
      @item
   </button>
}
<div id="popper" @ref=tooltip role="tooltip" style="height:50px;width:100px;">
    Popper
</div>

also, do you have some guidance regarding disposing / destroying the instance?

Feature: Support Blazor Server

Description

CreatePopperAsync results in an exception,

An exception occurred executing JS interop: Deserialization of interface types is not supported. Type 'Microsoft.JSInterop.IJSInProcessObjectReference'. Path: $ | LineNumber: 0 | BytePositionInLine: 1.. See InnerException for more details.

with inner exception,

Deserialization of interface types is not supported. Type 'Microsoft.JSInterop.IJSInProcessObjectReference'.

Specifically, this exception is thrown on https://github.com/KristofferStrube/Blazor.Popper/blob/6fcc66ec82c10082883c2522f418049d28654481/src/KristofferStrube.Blazor.Popper/Popper.cs#L25C45-L25C85:

/* Line 25 below, KristofferStrube.Blazor.Popper/Popper.cs */
var popperWrapper = await jSRuntime.InvokeAsync<IJSInProcessObjectReference>("import", "./_content/KristofferStrube.Blazor.Popper/KristofferStrube.Blazor.popper.js");

It should also be a problem on the other overloaded version of the same method, though I have not tested it yet.

Reproduction Steps

  1. Re-create https://github.com/KristofferStrube/Blazor.Popper/blob/main/samples/KristofferStrube.Blazor.Popper.Samples/Pages/VirtualElementReference.razor using .NET 8 (8.0.100-rc.2.23502.2), Microsoft.AspNetCore.App 8.0.0-rc.2.23480.2 within a MAUI Blazor hybrid application
  2. Run the solution.
  3. Step through to the line https://github.com/KristofferStrube/Blazor.Popper/blob/6fcc66ec82c10082883c2522f418049d28654481/samples/KristofferStrube.Blazor.Popper.Samples/Pages/VirtualElementReference.razor#L38C13-L38C89
    instance = await Popper.CreatePopperAsync(virtualElement, tooltip, options);

Expected behavior

Injection of the Popper.js JavaScript interop (./_content/KristofferStrube.Blazor.Popper/KristofferStrube.Blazor.popper.js) into the Blazor page.

Actual behavior

Popper.CreatePopperAsync fails with Deserialization of interface types is not supported exception.

Regression?

The current sample implementation is working correctly, which suggests that a breaking change in ASP.NET stopped the de-serialization of the Microsoft.JSInterop.IJSInProcessObjectReference interface.

Known Workarounds

None known.

Configuration

Microsoft Windows 10.0.19045, OSDImageName is Windows 10 x64 21H2 v8.0.
The version of .NET I am using is .NET 8.0 (8.0.100-rc.2.23502.2). Microsoft.AspNetCore.Components 8.0.0-rc.2.23480.2
The target frameworks I am using are net8.0-android, net8.0-ios, net8.0-maccatalyst, and net8.0-windows10.0.19041.0.
The supported OS platform versions are 14.2 for iOS, 14.0 for MacCatalyst, 24.0 for Android, 10.0.17763.0 for Windows, and 6.5 for Tizen.
The application title is Bombardier XML Splitter and the application ID is com.bombardier.mauixmlsplitter.
The project URL is https://github.com/Technical-Publications-Bombardier/BaXmlSplitter and the repository type is git.

Other information

See related issues:

dotnet/aspnetcore#29981
dotnet/aspnetcore#45440

Exception Throw when using in Blazor Server

Hi there and thank you for building this library. I'm doing a project with Blazor Server and when I try to use it an exception is thrown as bellow:

Error: Microsoft.JSInterop.JSException: An exception occurred executing JS interop: Deserialization of interface types is not supported. Type 'Microsoft.JSInterop.IJSInProcessObjectReference'. Path: $ | LineNumber: 0 | BytePositionInLine: 1.. See InnerException for more details.
---> System.NotSupportedException: Deserialization of interface types is not supported. Type 'Microsoft.JSInterop.IJSInProcessObjectReference'. Path: $ | LineNumber: 0 | BytePositionInLine: 1.
---> System.NotSupportedException: Deserialization of interface types is not supported. Type 'Microsoft.JSInterop.IJSInProcessObjectReference'.

I could it be because of the type of Blazor I'm using?

CSS Selector instead ElementReference

Hi,

In some scenarios, e.g. #2, it would be very convenient if we could just pass a css selector instead ElementRef:

string referenceSelector = $"[data-index={Index}]";
string popperReference = "#popover";
await Popper.CreatePopperAsync(referenceSelector, popperReference, new());

Theoretically it could go event further, so to that we scope the css selector to particular component

ElementReference rootElement; 
string referenceSelector = $"[data-index={Index}]";
string popperReference = "#popover";
await Popper.CreatePopperAsync(rootElement, referenceSelector, popperReference, new());
//js: let reference = rootElement.querySelector(referenceSelector);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.