fix(BUG-2): drive sidebar collapse/expand via CSS attribute, not Alpine reactivity
x-show and :class bindings inside @persist blocks do not re-evaluate when Alpine store changes. Replace all collapse-dependent bindings with CSS utility classes (nim-sb-expanded, nim-sb-collapsed, sidebar-nav-link) driven by html[data-sidebar-collapsed] in the critical inline style block. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>main
parent
3897d54ba3
commit
e71bd33e63
|
|
@ -104,14 +104,14 @@
|
|||
<!-- Header: Logo + Workspace Switcher -->
|
||||
<div class="flex-shrink-0 relative" @click.outside="wsOpen = false">
|
||||
<!-- Collapsed state: centered logo acts as expand toggle -->
|
||||
<div x-show="$store.sidebar.isCollapsed" class="flex items-center justify-center py-4 border-b border-white/[.06]">
|
||||
<div class="nim-sb-collapsed flex items-center justify-center py-4 border-b border-white/[.06]">
|
||||
<button @click="$store.sidebar.toggle()" title="Expand sidebar" class="flex items-center justify-center w-7 h-7 hover:opacity-75 transition-opacity">
|
||||
<img src="/brand/logo-mark.svg" alt="Nimuli" class="w-7 h-7">
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Expanded state: full header with workspace switcher -->
|
||||
<div x-show="!$store.sidebar.isCollapsed">
|
||||
<div class="nim-sb-expanded">
|
||||
<div class="flex items-stretch border-b border-white/[.06]">
|
||||
<button
|
||||
@click="wsOpen = !wsOpen"
|
||||
|
|
@ -192,8 +192,7 @@
|
|||
data-nav-link="{{ $item['route'] }}"
|
||||
@if(in_array($item['route'], ['w.dashboard', 'dashboard'])) data-nav-exact="1" @endif
|
||||
:title="$store.sidebar.isCollapsed ? '{{ $item['label'] }}' : ''"
|
||||
:class="$store.sidebar.isCollapsed ? 'justify-center px-2 gap-0' : 'gap-3 px-3'"
|
||||
class="flex items-center py-2 rounded-lg text-sm transition-colors group
|
||||
class="sidebar-nav-link flex items-center py-2 rounded-lg text-sm transition-colors group
|
||||
{{ $isActive
|
||||
? 'bg-blue/10 text-blue'
|
||||
: 'text-t2 hover:text-t1 hover:bg-s2' }}"
|
||||
|
|
@ -241,7 +240,7 @@
|
|||
</svg>
|
||||
@endif
|
||||
</span>
|
||||
<span x-show="!$store.sidebar.isCollapsed" class="truncate">{{ $item['label'] }}</span>
|
||||
<span class="nim-sb-expanded truncate">{{ $item['label'] }}</span>
|
||||
</a>
|
||||
@endforeach
|
||||
</nav>
|
||||
|
|
@ -251,23 +250,23 @@
|
|||
<button
|
||||
@click="$store.sidebar.toggle()"
|
||||
:title="$store.sidebar.isCollapsed ? 'Expand sidebar' : 'Collapse sidebar'"
|
||||
class="flex items-center gap-3 w-full px-3 py-2 rounded-lg text-t3 hover:text-t1 hover:bg-s2 transition-colors"
|
||||
class="sidebar-nav-link flex items-center w-full py-2 rounded-lg text-t3 hover:text-t1 hover:bg-s2 transition-colors"
|
||||
>
|
||||
<span class="w-4 h-4 flex-shrink-0">
|
||||
<svg x-show="!$store.sidebar.isCollapsed" fill="none" viewBox="0 0 16 16" stroke="currentColor" stroke-width="1.5">
|
||||
<svg class="nim-sb-expanded" fill="none" viewBox="0 0 16 16" stroke="currentColor" stroke-width="1.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M10 3L5 8l5 5"/>
|
||||
</svg>
|
||||
<svg x-show="$store.sidebar.isCollapsed" x-cloak fill="none" viewBox="0 0 16 16" stroke="currentColor" stroke-width="1.5">
|
||||
<svg class="nim-sb-collapsed" fill="none" viewBox="0 0 16 16" stroke="currentColor" stroke-width="1.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 3l5 5-5 5"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span x-show="!$store.sidebar.isCollapsed" class="text-xs">Collapse</span>
|
||||
<span class="nim-sb-expanded text-xs">Collapse</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Plan Usage Box -->
|
||||
@if($workspace && $plan)
|
||||
<div x-show="!$store.sidebar.isCollapsed" class="mx-3 mb-3 p-3 bg-s2 border border-white/[.06] rounded-lg">
|
||||
<div class="nim-sb-expanded mx-3 mb-3 p-3 bg-s2 border border-white/[.06] rounded-lg">
|
||||
<div class="flex items-center justify-between mb-1.5">
|
||||
<span class="text-xs font-medium text-t2">{{ ucfirst($plan->name) }} Plan</span>
|
||||
@if(str_contains(strtolower($plan->name), 'free'))
|
||||
|
|
@ -290,11 +289,11 @@
|
|||
<div class="w-8 h-8 rounded-full bg-blue flex items-center justify-center text-white text-xs font-semibold flex-shrink-0">
|
||||
{{ $initials ?: strtoupper(substr(auth()->user()->email, 0, 2)) }}
|
||||
</div>
|
||||
<div x-show="!$store.sidebar.isCollapsed" class="flex-1 min-w-0">
|
||||
<div class="nim-sb-expanded flex-1 min-w-0">
|
||||
<div class="text-xs font-medium text-t1 truncate">{{ auth()->user()->name }}</div>
|
||||
<div class="text-xs text-t3 truncate">{{ auth()->user()->email }}</div>
|
||||
</div>
|
||||
<form x-show="!$store.sidebar.isCollapsed" method="POST" action="{{ route('logout') }}">
|
||||
<form class="nim-sb-expanded" method="POST" action="{{ route('logout') }}">
|
||||
@csrf
|
||||
<button
|
||||
type="submit"
|
||||
|
|
|
|||
|
|
@ -89,12 +89,18 @@
|
|||
}
|
||||
html[data-sidebar-collapsed] .skel-sidebar { width: 64px; }
|
||||
html[data-sidebar-collapsed] .skel-topbar { left: 64px; }
|
||||
.sidebar-aside { width: 15rem; }
|
||||
.sidebar-aside { width: 15rem; overflow-x: hidden; }
|
||||
@media (min-width: 768px) {
|
||||
.nim-content { margin-left: 210px; }
|
||||
html[data-sidebar-collapsed] .nim-content { margin-left: 55px; }
|
||||
html[data-sidebar-collapsed] .sidebar-aside { width: 4rem; }
|
||||
}
|
||||
/* Sidebar collapsed/expanded visibility — CSS-driven, bypasses @persist Alpine issue */
|
||||
html[data-sidebar-collapsed] .nim-sb-expanded { display: none !important; }
|
||||
.nim-sb-collapsed { display: none !important; }
|
||||
html[data-sidebar-collapsed] .nim-sb-collapsed { display: flex !important; }
|
||||
.sidebar-nav-link { gap: 0.75rem; padding-left: 0.75rem; padding-right: 0.75rem; }
|
||||
html[data-sidebar-collapsed] .sidebar-nav-link { justify-content: center; padding-left: 0.5rem; padding-right: 0.5rem; gap: 0; }
|
||||
body.app-ready .app-spinner,
|
||||
body.app-ready .skel-sidebar,
|
||||
body.app-ready .skel-topbar { display: none; }
|
||||
|
|
|
|||
Loading…
Reference in New Issue