/** * Controls Module * * Handles generic UI controls functionality: * - Toggle sliders (Ja/Nej switches) * - Select dropdowns (Popover API) */ /** * Controller for generic UI controls */ export class ControlsController { constructor() { this.initToggleSliders(); this.initSelectDropdowns(); } /** * Initialize all toggle sliders on the page * Toggle slider: Ja/Nej button switch with data-value attribute * Clicking anywhere on the slider toggles the value */ private initToggleSliders(): void { document.querySelectorAll('swp-toggle-slider').forEach(slider => { slider.addEventListener('click', () => { const el = slider as HTMLElement; const newValue = el.dataset.value === 'yes' ? 'no' : 'yes'; el.dataset.value = newValue; // Dispatch custom event for listeners slider.dispatchEvent(new CustomEvent('toggle', { bubbles: true, detail: { value: newValue } })); }); }); } /** * Initialize all select dropdowns on the page * Uses Popover API for dropdown behavior */ private initSelectDropdowns(): void { document.querySelectorAll('swp-select').forEach(select => { const trigger = select.querySelector('button'); const popover = select.querySelector('[popover]') as HTMLElement | null; const options = select.querySelectorAll('swp-select-option'); if (!trigger || !popover) return; // Update aria-expanded on toggle popover.addEventListener('toggle', (e: Event) => { const event = e as ToggleEvent; trigger.setAttribute('aria-expanded', event.newState === 'open' ? 'true' : 'false'); }); // Handle option selection options.forEach(option => { option.addEventListener('click', () => { const value = (option as HTMLElement).dataset.value; const label = option.textContent?.trim() || ''; // Update selected state options.forEach(o => o.classList.remove('selected')); option.classList.add('selected'); // Update trigger display const valueEl = trigger.querySelector('swp-select-value'); if (valueEl) { valueEl.textContent = label; } // Update data-value on select element (select as HTMLElement).dataset.value = value; // Close popover popover.hidePopover(); // Dispatch custom event select.dispatchEvent(new CustomEvent('change', { bubbles: true, detail: { value, label } })); }); }); }); } }