Added extensive component library with feedback components (empty state, loading spinner, skeleton loader), enhanced form components (autocomplete, date picker, file upload, form field, time picker), navigation components (pagination), and overlay components (backdrop, drawer, modal, overlay container). Updated demo application with comprehensive showcase components and enhanced styling throughout the project. Excluded font files from repository to reduce size. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
294 lines
8.7 KiB
TypeScript
294 lines
8.7 KiB
TypeScript
import { Component } from '@angular/core';
|
|
import { CommonModule } from '@angular/common';
|
|
import { FormsModule } from '@angular/forms';
|
|
import { LoadingSpinnerComponent } from 'ui-essentials';
|
|
|
|
@Component({
|
|
selector: 'ui-loading-spinner-demo',
|
|
standalone: true,
|
|
imports: [CommonModule, FormsModule, LoadingSpinnerComponent],
|
|
template: `
|
|
<div class="demo-container">
|
|
<h2>Loading Spinner Demo</h2>
|
|
|
|
<!-- Size Variants -->
|
|
<section class="demo-section">
|
|
<h3>Sizes</h3>
|
|
<div class="demo-row">
|
|
@for (size of sizes; track size) {
|
|
<div class="demo-item">
|
|
<ui-loading-spinner [size]="size"></ui-loading-spinner>
|
|
<p>{{ size }}</p>
|
|
</div>
|
|
}
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Type Variants -->
|
|
<section class="demo-section">
|
|
<h3>Types</h3>
|
|
<div class="demo-row">
|
|
@for (type of types; track type) {
|
|
<div class="demo-item">
|
|
<ui-loading-spinner [type]="type"></ui-loading-spinner>
|
|
<p>{{ type }}</p>
|
|
</div>
|
|
}
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Color Variants -->
|
|
<section class="demo-section">
|
|
<h3>Colors</h3>
|
|
<div class="demo-row">
|
|
@for (variant of variants; track variant) {
|
|
<div class="demo-item">
|
|
<ui-loading-spinner [variant]="variant"></ui-loading-spinner>
|
|
<p>{{ variant }}</p>
|
|
</div>
|
|
}
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Speed Variants -->
|
|
<section class="demo-section">
|
|
<h3>Speeds</h3>
|
|
<div class="demo-row">
|
|
@for (speed of speeds; track speed) {
|
|
<div class="demo-item">
|
|
<ui-loading-spinner [speed]="speed" type="spin"></ui-loading-spinner>
|
|
<p>{{ speed }}</p>
|
|
</div>
|
|
}
|
|
</div>
|
|
</section>
|
|
|
|
<!-- With Labels -->
|
|
<section class="demo-section">
|
|
<h3>With Labels</h3>
|
|
<div class="demo-row">
|
|
<div class="demo-item">
|
|
<ui-loading-spinner
|
|
label="Loading data"
|
|
[showLabel]="true"
|
|
type="spin">
|
|
</ui-loading-spinner>
|
|
<p>With Label</p>
|
|
</div>
|
|
<div class="demo-item">
|
|
<ui-loading-spinner
|
|
label="Processing"
|
|
[showLabel]="true"
|
|
type="dots"
|
|
variant="success">
|
|
</ui-loading-spinner>
|
|
<p>Processing</p>
|
|
</div>
|
|
<div class="demo-item">
|
|
<ui-loading-spinner
|
|
label="Uploading"
|
|
[showLabel]="true"
|
|
type="bars"
|
|
variant="info">
|
|
</ui-loading-spinner>
|
|
<p>Uploading</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- States -->
|
|
<section class="demo-section">
|
|
<h3>States</h3>
|
|
<div class="demo-row">
|
|
<div class="demo-item">
|
|
<ui-loading-spinner></ui-loading-spinner>
|
|
<p>Normal</p>
|
|
</div>
|
|
<div class="demo-item">
|
|
<ui-loading-spinner [disabled]="true"></ui-loading-spinner>
|
|
<p>Disabled</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Interactive Example -->
|
|
<section class="demo-section">
|
|
<h3>Interactive</h3>
|
|
<div class="demo-interactive">
|
|
<div class="demo-controls">
|
|
<label>
|
|
Size:
|
|
<select [(ngModel)]="selectedSize">
|
|
@for (size of sizes; track size) {
|
|
<option [value]="size">{{ size }}</option>
|
|
}
|
|
</select>
|
|
</label>
|
|
|
|
<label>
|
|
Type:
|
|
<select [(ngModel)]="selectedType">
|
|
@for (type of types; track type) {
|
|
<option [value]="type">{{ type }}</option>
|
|
}
|
|
</select>
|
|
</label>
|
|
|
|
<label>
|
|
Variant:
|
|
<select [(ngModel)]="selectedVariant">
|
|
@for (variant of variants; track variant) {
|
|
<option [value]="variant">{{ variant }}</option>
|
|
}
|
|
</select>
|
|
</label>
|
|
|
|
<label>
|
|
Speed:
|
|
<select [(ngModel)]="selectedSpeed">
|
|
@for (speed of speeds; track speed) {
|
|
<option [value]="speed">{{ speed }}</option>
|
|
}
|
|
</select>
|
|
</label>
|
|
|
|
<label>
|
|
<input type="checkbox" [(ngModel)]="showInteractiveLabel">
|
|
Show Label
|
|
</label>
|
|
|
|
<label>
|
|
<input type="checkbox" [(ngModel)]="isDisabled">
|
|
Disabled
|
|
</label>
|
|
</div>
|
|
|
|
<div class="demo-result">
|
|
<ui-loading-spinner
|
|
[size]="selectedSize"
|
|
[type]="selectedType"
|
|
[variant]="selectedVariant"
|
|
[speed]="selectedSpeed"
|
|
[showLabel]="showInteractiveLabel"
|
|
[disabled]="isDisabled"
|
|
[label]="interactiveLabel"
|
|
(clicked)="handleSpinnerClick($event)">
|
|
</ui-loading-spinner>
|
|
</div>
|
|
|
|
@if (clickCount > 0) {
|
|
<p>Spinner clicked: {{ clickCount }} times</p>
|
|
}
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Usage Examples -->
|
|
<section class="demo-section">
|
|
<h3>Common Usage Examples</h3>
|
|
<div class="demo-usage">
|
|
<div class="usage-example">
|
|
<h4>Loading Button</h4>
|
|
<button class="demo-button" [disabled]="isLoading" (click)="simulateLoading()">
|
|
@if (isLoading) {
|
|
<ui-loading-spinner size="sm" variant="secondary" type="spin"></ui-loading-spinner>
|
|
<span>Loading...</span>
|
|
} @else {
|
|
<span>Click to Load</span>
|
|
}
|
|
</button>
|
|
</div>
|
|
|
|
<div class="usage-example">
|
|
<h4>Page Loading</h4>
|
|
<div class="page-loading-example">
|
|
@if (pageLoading) {
|
|
<ui-loading-spinner
|
|
size="lg"
|
|
variant="primary"
|
|
type="pulse"
|
|
label="Loading page content"
|
|
[showLabel]="true">
|
|
</ui-loading-spinner>
|
|
} @else {
|
|
<div class="page-content">
|
|
<h5>Page Content</h5>
|
|
<p>This is the loaded content.</p>
|
|
<button (click)="simulatePageLoad()">Reload Page</button>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="usage-example">
|
|
<h4>Data Processing</h4>
|
|
<div class="processing-example">
|
|
@if (processing) {
|
|
<ui-loading-spinner
|
|
type="bars"
|
|
variant="success"
|
|
label="Processing data"
|
|
[showLabel]="true">
|
|
</ui-loading-spinner>
|
|
} @else {
|
|
<div class="process-result">
|
|
<p>✅ Data processed successfully!</p>
|
|
<button (click)="simulateProcessing()">Process Data</button>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
`,
|
|
styleUrl: './loading-spinner-demo.component.scss'
|
|
})
|
|
export class LoadingSpinnerDemoComponent {
|
|
sizes = ['sm', 'md', 'lg'] as const;
|
|
types = ['spin', 'dots', 'pulse', 'bars'] as const;
|
|
variants = ['primary', 'secondary', 'accent', 'success', 'warning', 'danger', 'info'] as const;
|
|
speeds = ['slow', 'normal', 'fast'] as const;
|
|
|
|
// Interactive demo state
|
|
selectedSize = 'md' as const;
|
|
selectedType = 'spin' as const;
|
|
selectedVariant = 'primary' as const;
|
|
selectedSpeed = 'normal' as const;
|
|
showInteractiveLabel = false;
|
|
isDisabled = false;
|
|
interactiveLabel = 'Loading';
|
|
clickCount = 0;
|
|
|
|
// Usage examples state
|
|
isLoading = false;
|
|
pageLoading = false;
|
|
processing = false;
|
|
|
|
handleSpinnerClick(event: MouseEvent): void {
|
|
if (!this.isDisabled) {
|
|
this.clickCount++;
|
|
console.log('Spinner clicked', event);
|
|
}
|
|
}
|
|
|
|
simulateLoading(): void {
|
|
this.isLoading = true;
|
|
setTimeout(() => {
|
|
this.isLoading = false;
|
|
}, 2000);
|
|
}
|
|
|
|
simulatePageLoad(): void {
|
|
this.pageLoading = true;
|
|
setTimeout(() => {
|
|
this.pageLoading = false;
|
|
}, 3000);
|
|
}
|
|
|
|
simulateProcessing(): void {
|
|
this.processing = true;
|
|
setTimeout(() => {
|
|
this.processing = false;
|
|
}, 2500);
|
|
}
|
|
} |