import { Component, EventEmitter, Input, Output } from '@angular/core';
import { VspIcon } from './icon.component';
/* ===================== Setting row ===================== */
/** A labelled row (title + optional description) with a trailing control slot. */
@Component({
selector: 'vsp-setting-row',
template: `
{{ title }}
@if (desc) {
{{ desc }}
}
`,
})
export class VspSettingRow {
@Input() title?: string;
@Input() desc?: string;
@Input() last = false;
}
/* ===================== Vertical tabs ===================== */
export type VerticalTabItem =
| string
| { value: string; label: string; icon?: string; badge?: string | number };
/** Vertical tab strip — a settings-style left rail. */
@Component({
selector: 'vsp-vertical-tabs',
imports: [VspIcon],
template: `
@for (t of tabs; track id(t)) {
}
`,
})
export class VspVerticalTabs {
@Input() tabs: VerticalTabItem[] = [];
@Input() value?: string;
@Output() valueChange = new EventEmitter();
id(t: VerticalTabItem): string {
return typeof t === 'string' ? t : t.value;
}
lbl(t: VerticalTabItem): string {
return typeof t === 'string' ? t : t.label;
}
ico(t: VerticalTabItem): string | undefined {
return typeof t === 'object' ? t.icon : undefined;
}
bdg(t: VerticalTabItem): string | number | undefined {
return typeof t === 'object' ? t.badge : undefined;
}
cls(t: VerticalTabItem): string {
return 'ui-vtab' + (this.value === this.id(t) ? ' on' : '');
}
pick(v: string): void {
this.value = v;
this.valueChange.emit(v);
}
}
/* ===================== Nav item ===================== */
/** A sidebar nav row — renders as an `` when `href` is set, else a `