You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The `SidebarManager` class in `scripts/components/sidebar.js` is the single source of truth for all sidebar toggle behavior. It is initialized by `main.js` on every page and handles two distinct modes:
105
+
106
+
-**Desktop (>=992px):** Toggles between full-width (280px) and collapsed (70px) sidebar via the `sidebar-collapsed` class on `#admin-wrapper`. State is persisted in `localStorage`.
107
+
-**Mobile (<992px):** Opens the sidebar as a slide-in overlay with a backdrop. Supports closing via backdrop click, Escape key, and scroll-lock on the body.
108
+
109
+
**Key elements:**
110
+
111
+
| Selector | Role |
112
+
|----------|------|
113
+
|`#admin-wrapper`| Receives `sidebar-collapsed` class on desktop |
114
+
|`#admin-sidebar`| The sidebar element; receives `show` class on mobile |
115
+
|`[data-sidebar-toggle]`| The hamburger button that triggers `toggle()`|
116
+
|`.sidebar-backdrop`| Semi-transparent overlay behind mobile sidebar |
117
+
118
+
**Important:** Do not add inline `<script>` blocks that also listen for `[data-sidebar-toggle]` clicks. The `SidebarManager` is the only handler needed. Duplicate listeners will cancel each other out on desktop (both toggle the same class on the same click).
119
+
100
120
### Dynamic Imports
101
121
102
122
Page components are loaded asynchronously for code splitting:
@@ -323,6 +343,113 @@ const chart = new ApexCharts(document.querySelector('#chart'), chartOptions);
323
343
chart.render();
324
344
```
325
345
346
+
## Sidebar & Responsive Layout
347
+
348
+
The template uses a consistent `lg` breakpoint (992px) across all responsive behavior. Below 992px the layout switches to a mobile-optimized mode.
On mobile, the sidebar is positioned off-screen with `transform: translateX(-100%)` and slides in when the `show` class is added:
381
+
382
+
```scss
383
+
// layout/_sidebar.scss
384
+
@media (max-width: 991.98px) {
385
+
.admin-sidebar {
386
+
transform: translateX(-100%);
387
+
z-index: 1041; // above backdrop, below modals
388
+
389
+
&.show {
390
+
transform: translateX(0);
391
+
box-shadow: 4px016pxrgba(0, 0, 0, 0.15);
392
+
}
393
+
}
394
+
}
395
+
```
396
+
397
+
The `.sidebar-backdrop` element provides a semi-transparent overlay behind the sidebar. It is created automatically by `SidebarManager` if not present in the HTML.
398
+
399
+
**Mobile sidebar behaviors:**
400
+
- Background scroll is locked (`overflow: hidden` on body) when sidebar is open
401
+
- Backdrop click closes the sidebar
402
+
- Escape key closes the sidebar
403
+
- Resizing from mobile to desktop cleans up overlay state and restores collapsed preference
404
+
405
+
### Hamburger Button Placement
406
+
407
+
The hamburger button (`[data-sidebar-toggle]`) lives inside the header navbar, immediately after the `.navbar-brand`. On desktop, it is absolutely positioned at the right edge of the sidebar:
408
+
409
+
```scss
410
+
// components/_hamburger.scss
411
+
@media (min-width: 992px) {
412
+
.admin-header.hamburger-menu {
413
+
position: absolute;
414
+
left: calc(var(--sidebar-width) -40px-0.5rem);
415
+
top: 50%;
416
+
transform: translateY(-50%);
417
+
}
418
+
}
419
+
```
420
+
421
+
On mobile, the hamburger sits in normal document flow within the navbar.
422
+
423
+
### Z-Index Layering
424
+
425
+
The template uses a deliberate z-index stack to avoid overlap conflicts:
0 commit comments