/**
* Arod Menu Bar Component
* A responsive navigation menu with search and theme toggle
*
* Usage:
*
* Papers
* Notes
* About
*
*/
// ============================================
// AROD-MENU - Main Menu Bar Component
// ============================================
class ArodMenu extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
this.render();
this.setupMobileToggle();
}
render() {
this.shadowRoot.innerHTML = `
`;
}
setupMobileToggle() {
const toggle = this.shadowRoot.querySelector('.mobile-toggle');
const items = this.shadowRoot.querySelector('.menu-items');
toggle?.addEventListener('click', () => {
items?.classList.toggle('mobile-open');
});
// Close menu when clicking outside
document.addEventListener('click', (e) => {
if (!this.contains(e.target)) {
items?.classList.remove('mobile-open');
}
});
}
}
// ============================================
// MENU-ITEM - Individual Menu Item Component
// ============================================
class MenuItem extends HTMLElement {
constructor() {
super();
// Store the original text content
this._label = '';
}
connectedCallback() {
// Capture the text content before any rendering
this._label = this.textContent.trim();
this.render();
this.setupNavigation();
}
render() {
const href = this.getAttribute('href') || '#';
// Style the menu-item element itself
this.style.cssText = `
display: inline-flex;
align-items: center;
height: 100%;
`;
// Create link element
const link = document.createElement('a');
link.href = href;
link.textContent = this._label;
link.style.cssText = `
color: var(--menu-text, #222);
text-decoration: none;
padding: 0.5rem 0.75rem;
border-radius: 4px;
transition: all 0.2s ease;
display: inline-block;
white-space: nowrap;
`;
// Clear and add link
this.innerHTML = '';
this.appendChild(link);
// Add hover effects directly to the link
link.addEventListener('mouseenter', () => {
link.style.color = 'var(--menu-hover, #0066cc)';
link.style.background = 'rgba(0, 102, 204, 0.1)';
});
link.addEventListener('mouseleave', () => {
if (!this.hasAttribute('active')) {
link.style.color = 'var(--menu-text, #222)';
link.style.background = 'transparent';
}
});
}
setupNavigation() {
// Mark active based on current path
const href = this.getAttribute('href');
const link = this.querySelector('a');
if (href && window.location.pathname === href) {
this.setAttribute('active', '');
if (link) {
link.style.color = 'var(--menu-hover, #0066cc)';
link.style.fontWeight = '500';
}
}
}
}
// Register components
customElements.define('arod-menu', ArodMenu);
customElements.define('menu-item', MenuItem);