import { Component, Input } from '@angular/core'; @Component({ selector: 'vsp-spinner', template: ``, }) export class VspSpinner { @Input() size: 'sm' | 'md' | 'lg' = 'md'; @Input() label?: string; get cls(): string { return 'ui-spinner' + (this.size === 'sm' ? ' sm' : '') + (this.size === 'lg' ? ' lg' : ''); } } export type IconButtonVariant = 'ghost' | 'subtle' | 'danger'; @Component({ selector: 'vsp-icon-button', template: ``, }) export class VspIconButton { @Input() label?: string; @Input() size: 'sm' | 'md' | 'lg' = 'md'; @Input() variant?: IconButtonVariant; @Input() loading = false; @Input() disabled = false; get cls(): string { return [ 'vsp-icon-btn', this.size === 'sm' ? 'vsp-icon-btn-sm' : '', this.size === 'lg' ? 'vsp-icon-btn-lg' : '', this.variant ? `vsp-icon-btn-${this.variant}` : '', ] .filter(Boolean) .join(' '); } } @Component({ selector: 'vsp-progress', template: `
@if (indeterminate) { } @else { }
`, }) export class VspProgress { @Input() value = 0; @Input() tone?: string; @Input() height = 6; @Input() max = 100; @Input() indeterminate = false; @Input() label?: string; get pct(): number { return Math.min(100, Math.max(0, (this.value / this.max) * 100)); } } @Component({ selector: 'vsp-skeleton', template: `
`, }) export class VspSkeleton { @Input() w: string | number = '100%'; @Input() h: string | number = 12; @Input() r: number = 7; px(v: string | number): string { return typeof v === 'number' ? `${v}px` : v; } }