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', () => {
this.isMobile = window.innerWidth < 768;
this.isCollapsed = this.collapsed && ! this.isMobile;
this._syncDataset();
});
},
_syncDataset() {
if (this.collapsed) {
if (this.isCollapsed) {
document.documentElement.dataset.sidebarCollapsed = '1';
} else {
delete document.documentElement.dataset.sidebarCollapsed;

View File

@ -98,8 +98,7 @@
<aside
x-data="{ wsOpen: false }"
:class="$store.sidebar.isCollapsed ? 'w-16' : 'w-60'"
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"
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"
:style="$store.sidebar?.mobileOpen ? 'translate: 0' : null"
>
<!-- Header: Logo + Workspace Switcher -->

View File

@ -19,7 +19,7 @@
<script>
(function () {
try {
if (localStorage.getItem('sidebarCollapsed') === 'true') {
if (localStorage.getItem('sidebarCollapsed') === 'true' && window.innerWidth >= 768) {
document.documentElement.dataset.sidebarCollapsed = '1';
}
} catch (e) {}
@ -92,6 +92,8 @@
@media (min-width: 768px) {
.nim-content { margin-left: 210px; }
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 .skel-sidebar,