PlanTempusApp/PlanTempus.Application/wwwroot/ts/modules/controls.ts

89 lines
2.6 KiB
TypeScript
Raw Normal View History

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