Skip to content

Blazor: ToggleEvent of dialog/details/popover is handled with blank EventArgs instead of ToggleEventArgs #66479

@Flachdachs

Description

@Flachdachs

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

HTML elements with popover attribute, as well as <dialog>, and <details> fire a toggle event of type ToggleEvent. You will need the properties newState and oldState to know whether the element is now shown or hidden. Blazor already handles this toggle event, but creates an empty EventArgs. This event is currently of little use in its current form.

I found some relevant code.

Here is the toggle event configured but not treated as ToggleEvent. (cancel and close (only <dialog>) are fine, they are just generic Events. Although it would be nice to be able to read the returnValue string property in C# without additional JS interop.)

registerBuiltInEventType([
'cancel',
'close',
'toggle',
], createBlankEventArgsOptions);

The next place is the C# side. A ToggleEventArgs class needs to be created too. (As mentioned above, <dialog> and popover are affected too.)

// <details>
[EventHandler("ontoggle", typeof(EventArgs), true, true)]

I don't know if there are other places that need to be changed.

Expected Behavior

Fire the ToggleEvent with proper ToggleEventArgs.

Steps To Reproduce

Create a blank "Blazor Web App", render mode server, interactive rendering globally enabled.

Change Components/Pages/Home.razor to

@page "/"
@inject IJSRuntime js

<PageTitle>Home</PageTitle>

<h1>Hello, world!</h1>

<button @onclick="@onOpen">Open Modal</button>

<dialog @ref="dialog" @ontoggle="@onToggle">
    <div>Content</div>
</dialog>

@code {
    private IJSObjectReference? module;
    private ElementReference dialog;

    private void onOpen() => _ = module?.InvokeVoidAsync("showModal", dialog);

    protected override async Task OnAfterRenderAsync(bool firstRender) {
        await base.OnAfterRenderAsync(firstRender);
        if (firstRender)
            module = await js.InvokeAsync<IJSObjectReference>("import", "./Components/Pages/Home.razor.js");
    }

    private Task onToggle(EventArgs arg) {
        Console.WriteLine(arg.GetType());
        return Task.CompletedTask;
    }
}

Create Components/Pages/Home.razor.js

export const showModal = (element) => element.showModal();

You can examine the arg in the onToggle() method. The dialog can be closed with the Esc key.

Exceptions (if any)

No response

.NET Version

10.0.202

Anything else?

There is also a beforetoggle event, which is also a ToggleEvent. But I don't think this is useful, because you can't cancel this event in C#.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions