- Move layout components from layouts/ directory to components/layout/ - Reorganize divider component from data-display to layout category - Add comprehensive layout component collection including aspect-ratio, bento-grid, box, breakpoint-container, center, column, dashboard-shell, feed-layout, flex, grid-container, hstack, list-detail-layout, scroll-container, section, sidebar-layout, stack, supporting-pane-layout, tabs-container, and vstack - Update all demo components to match new layout structure - Refactor routing and index exports to reflect reorganized component architecture 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
246 lines
8.6 KiB
TypeScript
246 lines
8.6 KiB
TypeScript
import { Component } from '@angular/core';
|
|
import { CommonModule } from '@angular/common';
|
|
import { AspectRatioComponent } from '../../../../../ui-essentials/src/lib/components/layout/aspect-ratio';
|
|
|
|
@Component({
|
|
selector: 'ui-aspect-ratio-demo',
|
|
standalone: true,
|
|
imports: [CommonModule, AspectRatioComponent],
|
|
template: `
|
|
<div class="demo-container">
|
|
<h2>Aspect Ratio Demo</h2>
|
|
<p>Components for maintaining consistent aspect ratios across responsive content.</p>
|
|
|
|
<!-- Common Presets -->
|
|
<section class="demo-section">
|
|
<h3>Aspect Ratio Presets</h3>
|
|
<div class="demo-grid">
|
|
@for (preset of presets; track preset.ratio) {
|
|
<div class="demo-item">
|
|
<h4>{{ preset.label }}</h4>
|
|
<ui-aspect-ratio [ratio]="preset.ratio">
|
|
<div class="demo-content" [style.background]="getRandomColor()">
|
|
<span>{{ preset.ratio }} ({{ preset.description }})</span>
|
|
</div>
|
|
</ui-aspect-ratio>
|
|
</div>
|
|
}
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Custom Ratios -->
|
|
<section class="demo-section">
|
|
<h3>Custom Aspect Ratios</h3>
|
|
<div class="demo-grid">
|
|
@for (custom of customRatios; track custom.ratio) {
|
|
<div class="demo-item">
|
|
<h4>{{ custom.label }}</h4>
|
|
<ui-aspect-ratio [customRatio]="custom.ratio">
|
|
<div class="demo-content" [style.background]="getRandomColor()">
|
|
<span>{{ custom.ratio }}</span>
|
|
</div>
|
|
</ui-aspect-ratio>
|
|
</div>
|
|
}
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Size Variants -->
|
|
<section class="demo-section">
|
|
<h3>Size Variants</h3>
|
|
<div class="demo-row">
|
|
@for (size of sizes; track size) {
|
|
<div class="demo-item" style="flex: 1;">
|
|
<h4>Size: {{ size }}</h4>
|
|
<ui-aspect-ratio ratio="video" [size]="size">
|
|
<div class="demo-content" style="background: linear-gradient(45deg, #667eea, #764ba2)">
|
|
<span>{{ size }} size</span>
|
|
</div>
|
|
</ui-aspect-ratio>
|
|
</div>
|
|
}
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Style Variants -->
|
|
<section class="demo-section">
|
|
<h3>Style Variants</h3>
|
|
<div class="demo-grid">
|
|
@for (variant of variants; track variant) {
|
|
<div class="demo-item">
|
|
<h4>{{ variant | titlecase }}</h4>
|
|
<ui-aspect-ratio
|
|
ratio="photo"
|
|
[variant]="variant"
|
|
(clicked)="variant === 'interactive' ? handleInteractiveClick($event) : null">
|
|
<div class="demo-content" [style.background]="getRandomColor()">
|
|
<span>{{ variant }} variant</span>
|
|
@if (variant === 'interactive') {
|
|
<small>Click me!</small>
|
|
}
|
|
</div>
|
|
</ui-aspect-ratio>
|
|
</div>
|
|
}
|
|
</div>
|
|
</section>
|
|
|
|
<!-- With Images -->
|
|
<section class="demo-section">
|
|
<h3>Image Examples</h3>
|
|
<div class="demo-grid">
|
|
<div class="demo-item">
|
|
<h4>Square Image</h4>
|
|
<ui-aspect-ratio ratio="square" size="lg">
|
|
<img
|
|
src="https://picsum.photos/400/400"
|
|
alt="Square demo image"
|
|
style="object-fit: cover; width: 100%; height: 100%;">
|
|
</ui-aspect-ratio>
|
|
</div>
|
|
|
|
<div class="demo-item">
|
|
<h4>Video Aspect</h4>
|
|
<ui-aspect-ratio ratio="video" variant="elevated">
|
|
<img
|
|
src="https://picsum.photos/800/450"
|
|
alt="Video aspect demo image"
|
|
style="object-fit: cover; width: 100%; height: 100%;">
|
|
</ui-aspect-ratio>
|
|
</div>
|
|
|
|
<div class="demo-item">
|
|
<h4>Portrait Image</h4>
|
|
<ui-aspect-ratio ratio="portrait" variant="bordered">
|
|
<img
|
|
src="https://picsum.photos/400/533"
|
|
alt="Portrait demo image"
|
|
style="object-fit: cover; width: 100%; height: 100%;">
|
|
</ui-aspect-ratio>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Loading State -->
|
|
<section class="demo-section">
|
|
<h3>Loading State</h3>
|
|
<div class="demo-row">
|
|
<div class="demo-item" style="max-width: 300px;">
|
|
<h4>Loading</h4>
|
|
<ui-aspect-ratio ratio="video" [loading]="true">
|
|
<!-- Content is hidden when loading -->
|
|
</ui-aspect-ratio>
|
|
</div>
|
|
|
|
<div class="demo-item" style="max-width: 300px;">
|
|
<button (click)="toggleLoading()">
|
|
Toggle Loading: {{ isLoading ? 'ON' : 'OFF' }}
|
|
</button>
|
|
<ui-aspect-ratio ratio="square" [loading]="isLoading">
|
|
<div class="demo-content" style="background: linear-gradient(135deg, #ff6b6b, #4ecdc4)">
|
|
<span>Dynamic Loading</span>
|
|
</div>
|
|
</ui-aspect-ratio>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Centered Content -->
|
|
<section class="demo-section">
|
|
<h3>Content Centering</h3>
|
|
<div class="demo-grid">
|
|
<div class="demo-item">
|
|
<h4>Fill Container</h4>
|
|
<ui-aspect-ratio ratio="video" variant="bordered">
|
|
<div class="demo-content" style="background: linear-gradient(45deg, #fa709a, #fee140)">
|
|
<span>Fills entire container</span>
|
|
</div>
|
|
</ui-aspect-ratio>
|
|
</div>
|
|
|
|
<div class="demo-item">
|
|
<h4>Centered Content</h4>
|
|
<ui-aspect-ratio ratio="video" variant="bordered" [centerContent]="true">
|
|
<div style="background: #6c5ce7; color: white; padding: 20px; border-radius: 8px; text-align: center;">
|
|
<span>I'm centered!</span>
|
|
</div>
|
|
</ui-aspect-ratio>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Interactive Examples -->
|
|
<section class="demo-section">
|
|
<h3>Interactive Examples</h3>
|
|
<div class="demo-row">
|
|
<div class="demo-item">
|
|
<h4>Click Counter</h4>
|
|
<ui-aspect-ratio
|
|
ratio="square"
|
|
variant="interactive"
|
|
size="lg"
|
|
(clicked)="incrementCounter()">
|
|
<div class="demo-content" style="background: linear-gradient(135deg, #667eea, #764ba2); cursor: pointer;">
|
|
<div style="text-align: center; color: white;">
|
|
<div style="font-size: 2rem; font-weight: bold;">{{ clickCount }}</div>
|
|
<div>Click to increment</div>
|
|
</div>
|
|
</div>
|
|
</ui-aspect-ratio>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
`,
|
|
styleUrl: './aspect-ratio-demo.component.scss'
|
|
})
|
|
export class AspectRatioDemoComponent {
|
|
presets = [
|
|
{ ratio: 'square' as const, label: 'Square', description: '1:1' },
|
|
{ ratio: 'video' as const, label: 'Video', description: '16:9' },
|
|
{ ratio: 'cinema' as const, label: 'Cinema', description: '21:9' },
|
|
{ ratio: 'photo' as const, label: 'Photo', description: '3:2' },
|
|
{ ratio: 'portrait' as const, label: 'Portrait', description: '3:4' },
|
|
{ ratio: 'golden' as const, label: 'Golden', description: '1.618:1' }
|
|
];
|
|
|
|
customRatios = [
|
|
{ ratio: '4/3', label: 'Custom 4:3' },
|
|
{ ratio: '75%', label: 'Custom 75%' },
|
|
{ ratio: '1.33', label: 'Custom 1.33' },
|
|
{ ratio: '125%', label: 'Custom 125%' }
|
|
];
|
|
|
|
sizes = ['sm', 'md', 'lg'] as const;
|
|
variants = ['default', 'elevated', 'bordered', 'interactive'] as const;
|
|
|
|
clickCount = 0;
|
|
isLoading = false;
|
|
|
|
private colors = [
|
|
'linear-gradient(45deg, #667eea, #764ba2)',
|
|
'linear-gradient(135deg, #f093fb, #f5576c)',
|
|
'linear-gradient(45deg, #4facfe, #00f2fe)',
|
|
'linear-gradient(135deg, #43e97b, #38f9d7)',
|
|
'linear-gradient(45deg, #fa709a, #fee140)',
|
|
'linear-gradient(135deg, #a8edea, #fed6e3)',
|
|
'linear-gradient(45deg, #ffecd2, #fcb69f)',
|
|
'linear-gradient(135deg, #ff9a9e, #fecfef)'
|
|
];
|
|
|
|
getRandomColor(): string {
|
|
return this.colors[Math.floor(Math.random() * this.colors.length)];
|
|
}
|
|
|
|
handleInteractiveClick(event: MouseEvent): void {
|
|
console.log('Interactive aspect ratio clicked', event);
|
|
}
|
|
|
|
incrementCounter(): void {
|
|
this.clickCount++;
|
|
}
|
|
|
|
toggleLoading(): void {
|
|
this.isLoading = !this.isLoading;
|
|
}
|
|
} |