fix(bug-2): sidebar width via CSS attribute — bypasses @persist Alpine reactivity issue

@persist disconnects Alpine :class bindings from store reactivity on re-render.
Solution: drive sidebar width via html[data-sidebar-collapsed] CSS attribute
(same mechanism as skeleton) instead of Alpine :class.

- _syncDataset() now uses isCollapsed (respects mobile: never narrow on <768px)
- Blocking script checks window.innerWidth >= 768 before setting attribute
- Resize handler calls _syncDataset() to update attribute on viewport change
- aside gets sidebar-aside class; CSS sets 15rem/4rem at md+ via attribute

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
main
boban 2026-05-17 12:52:57 +02:00
parent fe257ef75b
commit 0a08d0f268
3 changed files with 6 additions and 4 deletions

View File

@ -70,10 +70,11 @@ document.addEventListener('alpine:init', () => {
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
this.isMobile = window.innerWidth < 768; this.isMobile = window.innerWidth < 768;
this.isCollapsed = this.collapsed && ! this.isMobile; this.isCollapsed = this.collapsed && ! this.isMobile;
this._syncDataset();
}); });
}, },
_syncDataset() { _syncDataset() {
if (this.collapsed) { if (this.isCollapsed) {
document.documentElement.dataset.sidebarCollapsed = '1'; document.documentElement.dataset.sidebarCollapsed = '1';
} else { } else {
delete document.documentElement.dataset.sidebarCollapsed; delete document.documentElement.dataset.sidebarCollapsed;

View File

@ -98,8 +98,7 @@
<aside <aside
x-data="{ wsOpen: false }" x-data="{ wsOpen: false }"
:class="$store.sidebar.isCollapsed ? 'w-16' : 'w-60'" class="sidebar-aside fixed inset-y-0 left-0 h-screen flex flex-col bg-s1 border-r border-white/[.06] z-40 -translate-x-full md:translate-x-0 transition-[width,transform] duration-200 ease-in-out"
class="fixed inset-y-0 left-0 h-screen flex flex-col bg-s1 border-r border-white/[.06] z-40 -translate-x-full md:translate-x-0 transition-[width,transform] duration-200 ease-in-out"
:style="$store.sidebar?.mobileOpen ? 'translate: 0' : null" :style="$store.sidebar?.mobileOpen ? 'translate: 0' : null"
> >
<!-- Header: Logo + Workspace Switcher --> <!-- Header: Logo + Workspace Switcher -->

View File

@ -19,7 +19,7 @@
<script> <script>
(function () { (function () {
try { try {
if (localStorage.getItem('sidebarCollapsed') === 'true') { if (localStorage.getItem('sidebarCollapsed') === 'true' && window.innerWidth >= 768) {
document.documentElement.dataset.sidebarCollapsed = '1'; document.documentElement.dataset.sidebarCollapsed = '1';
} }
} catch (e) {} } catch (e) {}
@ -92,6 +92,8 @@
@media (min-width: 768px) { @media (min-width: 768px) {
.nim-content { margin-left: 210px; } .nim-content { margin-left: 210px; }
html[data-sidebar-collapsed] .nim-content { margin-left: 55px; } html[data-sidebar-collapsed] .nim-content { margin-left: 55px; }
.sidebar-aside { width: 15rem; }
html[data-sidebar-collapsed] .sidebar-aside { width: 4rem; }
} }
body.app-ready .app-spinner, body.app-ready .app-spinner,
body.app-ready .skel-sidebar, body.app-ready .skel-sidebar,