/** * Navigation Component * Sidebar navigation with icons, active state highlighting, and mobile support */ class Navigation { constructor(container, options = {}) { this.container = container; this.options = { currentPath: options.currentPath || '/', version: options.version || '1.0.0', ...options }; this.items = [ { path: '/', label: 'Dashboard', icon: this.icons.dashboard }, { path: '/documents', label: 'Documents', icon: this.icons.documents }, { path: '/rules', label: 'Rules', icon: this.icons.rules }, { path: '/projects', label: 'Projects', icon: this.icons.projects }, { path: '/failures', label: 'Failures', icon: this.icons.failures }, { path: '/ide-tools', label: 'IDE Tools', icon: this.icons.ide } ]; this.render(); } get icons() { return { dashboard: '', documents: '', rules: '', projects: '', failures: '', ide: '', menu: '' }; } render() { this.container.innerHTML = ` `; this.attachEvents(); this.addMobileStyles(); } renderNavItem(item) { const isActive = this.options.currentPath === item.path; return ` `; } attachEvents() { // Mobile menu toggle const toggle = this.container.querySelector('#mobile-menu-toggle'); const sidebar = this.container.querySelector('#sidebar'); if (toggle) { toggle.addEventListener('click', () => { sidebar.classList.toggle('open'); }); } // Close mobile menu on navigation const links = this.container.querySelectorAll('.sidebar-nav-link'); links.forEach(link => { link.addEventListener('click', () => { if (window.innerWidth <= 768) { sidebar.classList.remove('open'); } }); }); // Close mobile menu when clicking outside document.addEventListener('click', (e) => { if (window.innerWidth <= 768 && sidebar.classList.contains('open') && !sidebar.contains(e.target) && !toggle.contains(e.target)) { sidebar.classList.remove('open'); } }); } updateActivePath(path) { this.options.currentPath = path; const links = this.container.querySelectorAll('.sidebar-nav-link'); links.forEach(link => { link.classList.toggle('active', link.dataset.path === path); }); } addMobileStyles() { if (!document.getElementById('mobile-nav-styles')) { const styles = document.createElement('style'); styles.id = 'mobile-nav-styles'; styles.textContent = ` @media (max-width: 768px) { :root { --sidebar-width-mobile: 280px; } .sidebar { transform: translateX(-100%); transition: transform 0.3s ease; width: var(--sidebar-width-mobile); } .sidebar.open { transform: translateX(0); } .mobile-menu-toggle { display: flex; align-items: center; justify-content: center; position: fixed; top: var(--space-4); left: var(--space-4); z-index: calc(var(--z-sticky) + 1); width: 40px; height: 40px; background-color: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-md); cursor: pointer; color: var(--color-text-primary); } .mobile-menu-toggle:hover { background-color: var(--color-surface-hover); } .mobile-menu-toggle svg { width: 20px; height: 20px; } .main { margin-left: 0; } .header { padding-left: calc(40px + var(--space-4) + var(--space-4)); } } @media (min-width: 769px) { .mobile-menu-toggle { display: none; } } `; document.head.appendChild(styles); } } } window.Navigation = Navigation;