/**
* 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;