import { Component, Input } from '@angular/core'; import { CommonModule } from '@angular/common'; @Component({ selector: 'app-loading-skeleton', standalone: true, imports: [CommonModule], template: `
@if (type === 'tree') {
@for (item of [1,2,3,4,5]; track item) {
}
} @if (type === 'card') {
} @if (type === 'list') {
@for (item of [1,2,3]; track item) {
}
} @if (type === 'form') {
@for (item of [1,2,3,4]; track item) {
}
}
`, styles: [` .skeleton-wrapper { padding: 1rem; } @keyframes shimmer { 0% { background-position: -468px 0; } 100% { background-position: 468px 0; } } .skeleton-line, .skeleton-circle, .skeleton-image, .skeleton-input { background: linear-gradient( to right, #f0f0f0 0%, #e0e0e0 20%, #f0f0f0 40%, #f0f0f0 100% ); background-size: 800px 104px; animation: shimmer 1.5s infinite linear; border-radius: 4px; } .skeleton-tree { display: flex; flex-direction: column; gap: 0.75rem; } .skeleton-tree-item { display: flex; align-items: center; gap: 0.75rem; } .skeleton-circle { width: 24px; height: 24px; border-radius: 50%; flex-shrink: 0; } .skeleton-line { height: 16px; width: 100%; &.short { width: 60%; } } .skeleton-card { border: 1px solid #e0e0e0; border-radius: 8px; overflow: hidden; } .skeleton-image { height: 200px; width: 100%; } .skeleton-text { padding: 1rem; display: flex; flex-direction: column; gap: 0.5rem; } .skeleton-list { display: flex; flex-direction: column; gap: 0.5rem; } .skeleton-list-item { padding: 1rem; border: 1px solid #e0e0e0; border-radius: 4px; } .skeleton-form { display: flex; flex-direction: column; gap: 1.5rem; } .skeleton-field { display: flex; flex-direction: column; gap: 0.5rem; } .skeleton-input { height: 56px; width: 100%; } `] }) export class LoadingSkeletonComponent { @Input() type: 'tree' | 'card' | 'list' | 'form' = 'list'; getRandomWidth(): string { const widths = ['60%', '70%', '80%', '90%']; return widths[Math.floor(Math.random() * widths.length)]; } }