initial
This commit is contained in:
123
static/components/Sidebar.js
Normal file
123
static/components/Sidebar.js
Normal file
@@ -0,0 +1,123 @@
|
||||
// Sidebar Component
|
||||
export class Sidebar {
|
||||
constructor() {
|
||||
this.sidebar = document.getElementById('sidebar');
|
||||
this.resizeHandle = document.getElementById('resizeHandle');
|
||||
this.menuToggle = null;
|
||||
this.isResizing = false;
|
||||
this.startX = 0;
|
||||
this.startWidth = 0;
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.createMenuToggle();
|
||||
this.setupResize();
|
||||
this.setupMobileBehavior();
|
||||
}
|
||||
|
||||
createMenuToggle() {
|
||||
// Create mobile menu toggle button
|
||||
this.menuToggle = document.createElement('button');
|
||||
this.menuToggle.className = 'mobile-menu-toggle';
|
||||
this.menuToggle.innerHTML = '☰';
|
||||
this.menuToggle.setAttribute('aria-label', 'Toggle menu');
|
||||
this.menuToggle.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
this.toggleMobile();
|
||||
});
|
||||
|
||||
// Create overlay for mobile
|
||||
this.overlay = document.createElement('div');
|
||||
this.overlay.className = 'sidebar-overlay';
|
||||
this.overlay.addEventListener('click', () => this.closeMobile());
|
||||
|
||||
// Insert at the beginning of body
|
||||
document.body.insertBefore(this.menuToggle, document.body.firstChild);
|
||||
document.body.appendChild(this.overlay);
|
||||
}
|
||||
|
||||
setupResize() {
|
||||
if (!this.resizeHandle || !this.sidebar) return;
|
||||
|
||||
this.resizeHandle.addEventListener('mousedown', (e) => {
|
||||
if (window.innerWidth <= 768) return; // Disable resize on mobile
|
||||
|
||||
this.isResizing = true;
|
||||
this.startX = e.clientX;
|
||||
this.startWidth = parseInt(window.getComputedStyle(this.sidebar).width, 10);
|
||||
document.addEventListener('mousemove', this.handleResize.bind(this));
|
||||
document.addEventListener('mouseup', this.stopResize.bind(this));
|
||||
e.preventDefault();
|
||||
});
|
||||
}
|
||||
|
||||
handleResize(e) {
|
||||
if (!this.isResizing) return;
|
||||
const width = this.startWidth + e.clientX - this.startX;
|
||||
const minWidth = 200;
|
||||
const maxWidth = 600;
|
||||
if (width >= minWidth && width <= maxWidth) {
|
||||
this.sidebar.style.width = `${width}px`;
|
||||
document.documentElement.style.setProperty('--sidebar-width', `${width}px`);
|
||||
}
|
||||
}
|
||||
|
||||
stopResize() {
|
||||
this.isResizing = false;
|
||||
document.removeEventListener('mousemove', this.handleResize);
|
||||
document.removeEventListener('mouseup', this.stopResize);
|
||||
}
|
||||
|
||||
setupMobileBehavior() {
|
||||
// Close sidebar on window resize if switching to desktop
|
||||
window.addEventListener('resize', () => {
|
||||
if (window.innerWidth > 768) {
|
||||
this.closeMobile();
|
||||
}
|
||||
});
|
||||
|
||||
// Close sidebar when clicking on module items or search button on mobile
|
||||
if (this.sidebar) {
|
||||
this.sidebar.addEventListener('click', (e) => {
|
||||
if (window.innerWidth <= 768) {
|
||||
// Close if clicking on interactive elements (but not the toggle itself)
|
||||
if (e.target.closest('.module-item') ||
|
||||
e.target.closest('.search-btn') ||
|
||||
e.target.closest('.nav-tab')) {
|
||||
// Small delay to allow the click to register
|
||||
setTimeout(() => this.closeMobile(), 100);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
toggleMobile() {
|
||||
const isOpen = this.sidebar?.classList.contains('open');
|
||||
if (isOpen) {
|
||||
this.closeMobile();
|
||||
} else {
|
||||
this.openMobile();
|
||||
}
|
||||
}
|
||||
|
||||
openMobile() {
|
||||
this.sidebar?.classList.add('open');
|
||||
if (this.overlay) {
|
||||
this.overlay.classList.add('active');
|
||||
}
|
||||
// Prevent body scroll when sidebar is open
|
||||
document.body.style.overflow = 'hidden';
|
||||
}
|
||||
|
||||
closeMobile() {
|
||||
this.sidebar?.classList.remove('open');
|
||||
if (this.overlay) {
|
||||
this.overlay.classList.remove('active');
|
||||
}
|
||||
// Restore body scroll
|
||||
document.body.style.overflow = '';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user