livewire / flux

The official Livewire UI component library
https://fluxui.dev
476 stars 42 forks source link

Cannot read properties of null when clicking flux:menu.item in dropdown inside a child component #331

Closed lordisp closed 1 month ago

lordisp commented 1 month ago

Description:

I am trying to implement a dropdown menu with edit and delete actions inside a table. The delete action works fine, but clicking the edit button (which triggers a modal from a child component) throws the following error:

Uncaught TypeError: Cannot read properties of null (reading 'localName')
    at _UIMenu.boot (flux.js?id=131aca24:4209:30)
    ...

The dropdown is located inside a table cell, and the edit action is meant to open a modal from a child component.

Steps to Reproduce:

  1. Parent component includes a dropdown menu inside a table cell using flux:dropdown.
  2. Child component renders an edit action within the dropdown.
  3. Clicking the edit button triggers a modal from the child component.

Parent Component Blade Code:

<x-livewire.table.cell class="w-0">
    <flux:dropdown>
        <flux:button variant="ghost" size="sm" inset="bottom top" icon="ellipsis-horizontal"/>
        <flux:menu>
            <livewire:admin.roles.index.update :key="$row->id" :roleId="$row->id"/>
            <flux:menu.item variant="danger" icon="trash">Delete</flux:menu.item>
        </flux:menu>
    </flux:dropdown>
</x-livewire.table.cell>

Child Component Blade Code:

<div>
    <flux:menu.item wire:click="edit('{{$roleId}}')" icon="pencil-square">Edit</flux:menu.item>

    <form wire:submit="update">
        <flux:modal wire:model.self="showEditModal" variant="flyout" name="edit-{{$roleId}}" class="space-y-6">
            <!-- modal content -->
        </flux:modal>
    </form>
</div>

Expected Behavior: Clicking the edit button in the dropdown should trigger the modal in the child component without any error.

Actual Behavior:

The following error is thrown when clicking the edit button:

Uncaught TypeError: Cannot read properties of null (reading 'localName')

Environment:

lordisp commented 1 month ago

I ended up with the solution to put the entire dropdown to the child component. I believe, my original approach may be to complex for flux..

Parent Component Blade Code:

<x-livewire.table.cell class="w-0">
    <flux:dropdown>
        <flux:button variant="ghost" size="sm" inset="bottom top" icon="ellipsis-horizontal"/>
        <flux:menu>
            <livewire:admin.roles.index.update :key="$row->id" :roleId="$row->id" :name="$row->name"/>
        </flux:menu>
    </flux:dropdown>
</x-livewire.table.cell>

Child Component Blade Code:

<div>
    <flux:dropdown>
        <flux:button variant="ghost" size="sm" inset="bottom top" icon="ellipsis-horizontal"/>
        <flux:menu>
                <flux:menu.item wire:click="edit('{{$roleId}}')" icon="pencil-square">Edit</flux:menu.item>
                <flux:menu.item wire:click="delete('{{$roleId}}')" wire:confirm.prompt="Are you sure you want to delete the role?\n\nType {{$name}} to confirm|{{$name}}" variant="danger" icon="trash">Delete</flux:menu.item>
        </flux:menu>
    </flux:dropdown>

    <form wire:submit="update">
        <flux:modal wire:model.self="showEditModal" variant="flyout" name="edit-{{$roleId}}" class="space-y-6">
            <!-- modal content -->
        </flux:modal>
    </form>
</div>
calebporzio commented 1 month ago

Thanks for this report, maybe we can really dig into deep, complex, combinations like this down the road, but for now I want to keep things simple. So let's close this for now. Thanks for the report though.