Move sidebar-collapsed class to <html> element
LiveView DOM patching was stripping the client-side sidebar-collapsed class from #sidebar-wrapper on every navigation. Fix: put the class on document.documentElement which LiveView never touches. - Sync script in <head> applies state before first paint (no flash) - Hook click handler toggles on <html> + saves to localStorage - CSS selectors updated to html.sidebar-collapsed - Removed phx-click JS.toggle_class (hook handles toggle directly)
This commit is contained in:
parent
7149ab71cd
commit
8e25034e69
4 changed files with 18 additions and 36 deletions
|
|
@ -109,25 +109,25 @@
|
|||
#app-sidebar {
|
||||
@apply w-56 transition-all duration-200;
|
||||
}
|
||||
.sidebar-collapsed #app-sidebar {
|
||||
html.sidebar-collapsed #app-sidebar {
|
||||
@apply w-16;
|
||||
}
|
||||
.sidebar-collapsed [data-sidebar-text] {
|
||||
html.sidebar-collapsed [data-sidebar-text] {
|
||||
display: none;
|
||||
}
|
||||
.sidebar-collapsed [data-sidebar-section] {
|
||||
html.sidebar-collapsed [data-sidebar-section] {
|
||||
display: none;
|
||||
}
|
||||
.sidebar-collapsed .sidebar-collapse-icon {
|
||||
html.sidebar-collapsed .sidebar-collapse-icon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
.sidebar-collapse-icon {
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
.sidebar-collapsed [data-sidebar-tooltip] {
|
||||
html.sidebar-collapsed [data-sidebar-tooltip] {
|
||||
position: relative;
|
||||
}
|
||||
.sidebar-collapsed [data-sidebar-tooltip]:hover::after {
|
||||
html.sidebar-collapsed [data-sidebar-tooltip]:hover::after {
|
||||
content: attr(data-sidebar-tooltip);
|
||||
position: absolute;
|
||||
left: 100%;
|
||||
|
|
@ -150,7 +150,7 @@
|
|||
#main-wrapper {
|
||||
margin-left: 14rem; /* w-56 = 224px */
|
||||
}
|
||||
.sidebar-collapsed #main-wrapper {
|
||||
html.sidebar-collapsed #main-wrapper {
|
||||
margin-left: 4rem; /* w-16 = 64px */
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1375,29 +1375,15 @@ const StatusTitle = {
|
|||
}
|
||||
}
|
||||
|
||||
// Sidebar collapse - restore state from localStorage and persist toggle.
|
||||
// Uses both mounted() and updated() because LiveView DOM patching can
|
||||
// strip the client-side "sidebar-collapsed" class on live navigations.
|
||||
// Sidebar collapse - toggle class on <html> (which LiveView never patches)
|
||||
// so the state persists across all navigations without flicker.
|
||||
const SidebarCollapse = {
|
||||
mounted(this: any) {
|
||||
this._apply()
|
||||
this._listen()
|
||||
},
|
||||
updated(this: any) {
|
||||
this._apply()
|
||||
},
|
||||
_apply(this: any) {
|
||||
if (localStorage.getItem('sidebarCollapsed') === 'true') {
|
||||
this.el.classList.add('sidebar-collapsed')
|
||||
}
|
||||
},
|
||||
_listen(this: any) {
|
||||
this.el.addEventListener('click', (e: Event) => {
|
||||
if ((e.target as HTMLElement).closest('[data-sidebar-toggle]')) {
|
||||
requestAnimationFrame(() => {
|
||||
const collapsed = this.el.classList.contains('sidebar-collapsed')
|
||||
localStorage.setItem('sidebarCollapsed', String(collapsed))
|
||||
})
|
||||
const html = document.documentElement
|
||||
html.classList.toggle('sidebar-collapsed')
|
||||
localStorage.setItem('sidebarCollapsed', String(html.classList.contains('sidebar-collapsed')))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -149,15 +149,6 @@ defmodule ToweropsWeb.Layouts do
|
|||
|
||||
~H"""
|
||||
<div id="sidebar-wrapper" phx-hook="SidebarCollapse" class="min-h-screen bg-gray-50 dark:bg-gray-950">
|
||||
<script>
|
||||
// Apply sidebar state synchronously to prevent flash on navigation
|
||||
(function() {
|
||||
var w = document.getElementById('sidebar-wrapper');
|
||||
if (w && localStorage.getItem('sidebarCollapsed') === 'true') {
|
||||
w.classList.add('sidebar-collapsed');
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<!-- Impersonation Banner -->
|
||||
<%= if @current_scope && @current_scope.impersonating? do %>
|
||||
<div class="bg-yellow-400 border-b-2 border-yellow-600 relative z-50">
|
||||
|
|
@ -487,7 +478,6 @@ defmodule ToweropsWeb.Layouts do
|
|||
<button
|
||||
type="button"
|
||||
data-sidebar-toggle
|
||||
phx-click={JS.toggle_class("sidebar-collapsed", to: "#sidebar-wrapper")}
|
||||
class="flex items-center justify-center w-full rounded-md px-3 py-2 text-gray-400 hover:bg-gray-50 hover:text-gray-600 dark:hover:bg-gray-800 dark:hover:text-gray-300 transition-colors"
|
||||
title={t("Toggle sidebar")}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -68,6 +68,12 @@
|
|||
window.addEventListener("phx:set-theme", (e) => setTheme(e.target.dataset.phxTheme));
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
// Apply sidebar collapsed state before paint (prevents flash)
|
||||
if (localStorage.getItem('sidebarCollapsed') === 'true') {
|
||||
document.documentElement.classList.add('sidebar-collapsed');
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue