The issue you're facing with both the + and - icons displaying is likely due to the way the x-show directive is being used in your menu/menu-arrow component. The x-show directive expects a JavaScript expression, but you're passing a Blade variable directly, which might not be evaluated correctly in the context of AlpineJS.
Here's a solution to ensure that the x-show directive works as expected:
-
Ensure
x-datais properly initialized: Make sure that thex-dataobject is correctly set up and that theopenstate is being toggled as expected. -
Use AlpineJS expressions in
x-show: Instead of using Blade syntax directly inx-show, use AlpineJS expressions. You can bind theisOpenstate to thex-dataobject and use it directly in yourx-showdirectives.
Here's how you can adjust your code:
x-sidebar.menu-item Component
<x-sidebar.menu-item
x-data="{
open: false,
toggle() {
this.open = !this.open;
this.$refs.button.focus();
},
close(focusAfter) {
if (!this.open) return;
this.open = false;
focusAfter && focusAfter.focus();
}
}"
>
<x-sidebar.menu-label :hasSub="true" :isOpen="open">
<x-sidebar.menu-icon icon="ki-people" />
<x-sidebar.menu-title>Groups</x-sidebar.menu-title>
</x-sidebar.menu-label>
<x-slot:subMenu :isOpen="open">
<x-sidebar.menu-link :href="route('users.index')">Users</x-sidebar.menu-link>
</x-slot:subMenu>
</x-sidebar.menu-item>
menu/menu-arrow Component
@props([
'isOpen' => false
])
<span class="flex items-center text-gray-400 w-[20px] shrink-0 justify-end ml-1 mr-[-10px]">
<i x-show="isOpen" class="ki-filled ki-minus text-2xs"></i>
<i x-show="!isOpen" class="ki-filled ki-plus text-2xs"></i>
</span>
Explanation
-
x-dataInitialization: Thex-dataobject is initialized with anopenproperty and atogglemethod to switch the state. This ensures that theopenstate is managed within the component. -
Passing
isOpen: TheisOpenproperty is passed as a prop to themenu-labelandsubMenuslots, and it is bound to theopenstate of thex-dataobject. -
AlpineJS Expressions: The
x-showdirectives in themenu/menu-arrowcomponent now use AlpineJS expressions (isOpenand!isOpen) to conditionally display the icons based on theopenstate.
This setup should correctly toggle between the + and - icons based on the menu's open state.