I'm using livewire and alpine to make a page with tabs. Every time a tab is clicked a different panel shows. Pretty straight forward however everytime i click a tab to change the panel I am getting this warning.
type hereAlpine Expression Error: can't access property "contains", $refs.panel is undefined
Expression: "! $refs.panel.contains($event.target) && close()"
<div class="relative" x-data="{\n open: fal… }\n }" @keydown.escape.prevent.stop="close()" x-id="['dropdown-button']" @focusin.window="! $refs.panel.contains($event.target) && close()">
and this error
Uncaught TypeError: can't access property "contains", $refs.panel is undefined
I have tried explicitly defining where my live wire js in my app service provider
<header>
<div class="bg-primaryBlack flex items-center justify-between px-8">
<div>
<a href="/">
<x-application-logo class="w-28 h-24" />
</a>
</div>
<div>
<nav>
<ul class="flex text-primaryWhite font-semibold">
<li class="mr-5">
<a
class="hover:text-gray-400 transition-colors ease-in-out"
href="#">Plaques</a>
</li>
<li class="mr-5">
<a
class="hover:text-gray-400 transition-colors ease-in-out"
href="#">Pens</a>
</li>
<li>
<a
class="hover:text-gray-400 transition-colors ease-in-out"
href="#">Lichtenberg</a>
</li>
</ul>
</nav>
</div>
{{--Parent--}}
<div
x-data="{
open: false,
toggle(){
this.open = this.open ? this.close() : true
},
close(focusAfter){
this.open=false
focusAfter && focusAfter.focus()
}
}"
@keydown.escape.prevent.stop="close()"
x-id="['dropdown-button']"
@focusin.window= "! $refs.panel.contains($event.target) && close()"
class="relative">
@if(Auth::user())
<div class="flex items-center relative">
{{-- Button --}}
<button
x-ref="button"
@click="toggle()"
type="button"
:aria-expanded="open"
:aria-controls="$id('dropdown-button')"
class="text-primaryWhite text-sm block mr-2"
href="{{ route('dashboard') }}">{{ auth()->user()->name }}</button>
<x-icons.right-caret class="w-5 h-5 fill-primaryWhite" />
<div class="absolute top-0 -left-7">
<x-icons.cart class="w-5 h-5 fill-primaryWhite"/>
<a class="absolute -top-3 -left-5 text-xs bg-red-400 px-1.5 rounded-full text-primaryWhite font-bold" href="#">5</a>
</div>
</div>
{{--Panel--}}
<div
x-ref="panel"
x-show="open"
@click.outside="close($refs.button)"
:id="$id('dropdown-button')"
style="display:none"
class="absolute top-10 right-3 z-10">
<ul class="bg-secondaryWhite px-4 text-left py-2 space-y-2 rounded uppercase text-sm">
<li class="hover:bg-primaryGreen hover:text-primaryWhite px-2 rounded">
<x-links.logout/>
</li>
<li class="hover:bg-primaryGreen hover:text-primaryWhite px-2 rounded">
<a href="{{ route('dashboard') }}">Dashboard</a>
</li>
<li class="hover:bg-primaryGreen hover:text-primaryWhite px-2 rounded">
<a href="#">Cart</a>
</li>
</ul>
</div>
@else
<a
class="font-semibold text-gray-300 mr-4 hover:text-gray-400 transition-colors ease-in-out"
href="{{ route('login') }}">Login</a>
<a
class="font-semibold text-gray-300 hover:text-gray-400 transition-colors ease-in-out"
href="{{ route('register') }}">Register</a>
@endif
</div>
</div>
</header>
The <div> that contains x-ref="panel":
<div
x-ref="panel"
x-show="open"
.....
is placed into an @if(Auth::user()) and in the @else branch there isn't any x-ref="panel", hence the error.
To solve the problem you can create a new <div> into the @if(Auth::user()) check and move the x-data and all the Alpine stuff there.