Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flowbite interactivity not working with Blazor 8 #49

Open
fdonnet opened this issue Nov 29, 2023 · 8 comments
Open

Flowbite interactivity not working with Blazor 8 #49

fdonnet opened this issue Nov 29, 2023 · 8 comments
Labels
bug Something isn't working

Comments

@fdonnet
Copy link

fdonnet commented Nov 29, 2023

Following this : https://flowbite.com/docs/getting-started/blazor/

All the flowbite specific things are not working in term of interactivitywith blazor 8

The dropdown example doesn't work.
The dropdown style applied seems not correct and the interactivity (onclick) is not working.

To Reproduce
Follow the configuration on the site on a fresh Blazor 8 project.

Expected behavior
Interactivity working

@fdonnet fdonnet added the bug Something isn't working label Nov 29, 2023
@tdashworth
Copy link
Collaborator

It's worth checking if this is a .net 8 issue or if it was preexisting.

Whenever I've worked with Flowbite in Blazor, I implemented the interactive logic myself in C# because the old JavaScript framework wasn't Blazor friendly.

@fdonnet
Copy link
Author

fdonnet commented Dec 1, 2023

That's what I m doing now. For the moment, a good result with modal compo based on the new html dialog and 2 lines of JS. I just begin with the inputs form integration and I suffer a little bit more with validation an stuff. ;)

As a "back-end guy", definitly loving flowbite theme and all the stuff.

The modal, for the fun below (microsoft style => open to the right for Add/Edit Form):

@inject IJSRuntime JS
<dialog id="@_dialogId" @onclose="OnClose" tabindex=" -1" class="bg-white/60 dark:bg-gray-900/80 overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-40 w-full md:inset-0 h-[calc(100%-1rem)] max-h-full max-w-full">
    <div class="flex  flex-row justify-between items-start shrink-0">
        <div class="grow"></div>
        <div class="fixed inset-y-0 right-0 w-full md:w-[768px]">
            <div class="relative bg-white shadow dark:bg-gray-700 h-full overflow-y-auto">
                <!-- Modal header -->
                <div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t dark:border-gray-600">
                    <h3 class="text-lg font-semibold text-gray-900 dark:text-white">
                        @DialogTitle
                    </h3>
                    <button @onclick="CloseDialog" type="button" class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white" data-modal-toggle="crud-modal">
                        <svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
                            <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
                        </svg>
                        <span class="sr-only">Close</span>
                    </button>
                </div>
                <!-- Modal body -->
                <div class="px-4 pt-2 pb-2 md:px-5 md:pt-3 md:pb-3">
                    @ChildContent
                </div>
            </div>
        </div>
    </div>
</dialog>

@code {
    [Parameter]
    public string DialogTitle { get; set; } = "Dialog box";
    [Parameter]
    public string ButtonLabel { get; set; } = "Show";
    [Parameter]
    public RenderFragment? ChildContent { get; set; }

    private IJSObjectReference? _jsModule = default!;
    private string _dialogId = $"dialog{Guid.NewGuid().ToString()}";

    public async Task ShowDialog()
    {
        await _jsModule!.InvokeVoidAsync("openDialog", _dialogId);
    }

    public async Task CloseDialog()
    {
        await _jsModule!.InvokeVoidAsync("closeDialog", _dialogId);
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            _jsModule = await JS.InvokeAsync<IJSObjectReference>(
                "import", "./Components/Common/Modal/UbikModal.razor.js");

            await _jsModule.InvokeVoidAsync("clickOutside", _dialogId);
        }
    }

    void OnClose(EventArgs e)
    {

    }
}

And the js:

export function openDialog(dialogId) {
  document.getElementById(dialogId).showModal();
}

export function closeDialog(dialogId) {
  document.getElementById(dialogId).close();
}

export function clickOutside(dialogId) {
  var dialog = document.getElementById(dialogId)

  dialog.addEventListener('click', function (e) {
    console.info(e.target.tagName);
    if (e.target.tagName === 'DIALOG') dialog.close()
  });
}

@tdashworth
Copy link
Collaborator

Flowbite has been a game changer for my UIs. Similar to you, I prefer the backend more.

Pleased to hear that. I haven't upgraded any of my projects yet.

@schaveyt
Copy link

schaveyt commented Mar 2, 2024

NOTE, the AfterRender() is only for called Interactive components. If you are using just Static SSR, then this is no bueno.

I hope to make a fork of this repo to shows examples of all 4 render modes.

  1. SSR w/ streaming
  2. InteractiveServer
  3. InteractiveWebassemly
  4. Interactive auto
    As well as a darkmode toggle

For 2 thru 4, I recommend creating a FlowBiteComponentBase.cs class the overrides the AfterRender and calls the overall flowbit.init() via JSRuntime.InvokeVkidAsync().

For 1. It's trickier as you must wait to call the flowbit.init() until after the stream rendering is complete and the DOM is fully available.

@Akinnagbe
Copy link

Is there a fix to this, even using PageScript still doesn't work and @schaveyt, I tried your example, still doesn't work as well.

@schaveyt
Copy link

schaveyt commented Mar 9, 2024

@Akinnagbe r u dealing with the issue around SSR?

@mihetah
Copy link

mihetah commented May 13, 2024

@schaveyt I have the issue with SSR where flowbite.init() is called to early. do you have an idea how to get it working?

EDIT: Okay solved it. I had to call flowbite.init() in OnAfterRenderAsync.

@kjbtech
Copy link

kjbtech commented Sep 26, 2024

As I said right here, to make it work with .NET 8 Blazor WASM, I had to use this:

    protected override async Task OnAfterRenderAsync(bool isFirstRender)
    {
        await Js.InvokeVoidAsync("window.initializeFlowbite");
    }

Caution: At this time, I do not now if it is good practice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants