Adds comprehensive service detail view with multiple tabs and dynamic interactions Implements client-side navigation between service list and detail views Introduces mock service data catalog for flexible component rendering Extends localization support for new service detail screens Improves user experience by adding edit capabilities and smooth view transitions
88 lines
2.6 KiB
TypeScript
88 lines
2.6 KiB
TypeScript
/**
|
|
* 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 }
|
|
}));
|
|
});
|
|
});
|
|
});
|
|
}
|
|
}
|