Add comprehensive component library and demo application

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>
This commit is contained in:
skyai_dev
2025-09-03 05:38:09 +10:00
parent c803831f60
commit 5983722793
246 changed files with 52845 additions and 25 deletions

View File

@@ -0,0 +1,523 @@
import { Component, ChangeDetectionStrategy, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { PaginationComponent } from '../../../../../ui-essentials/src/lib/components/navigation/pagination';
@Component({
selector: 'ui-pagination-demo',
standalone: true,
imports: [CommonModule, PaginationComponent],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div style="padding: 2rem;">
<h2>Pagination Component Showcase</h2>
<!-- Size Variants -->
<section style="margin-bottom: 3rem;">
<h3>Sizes</h3>
<div style="margin-bottom: 2rem;">
<h4>Small</h4>
<ui-pagination
[currentPage]="currentPageSmall"
[totalPages]="totalPagesDemo"
size="sm"
(pageChange)="onPageChange($event, 'small')">
</ui-pagination>
</div>
<div style="margin-bottom: 2rem;">
<h4>Medium (Default)</h4>
<ui-pagination
[currentPage]="currentPageMedium"
[totalPages]="totalPagesDemo"
size="md"
(pageChange)="onPageChange($event, 'medium')">
</ui-pagination>
</div>
<div style="margin-bottom: 2rem;">
<h4>Large</h4>
<ui-pagination
[currentPage]="currentPageLarge"
[totalPages]="totalPagesDemo"
size="lg"
(pageChange)="onPageChange($event, 'large')">
</ui-pagination>
</div>
</section>
<!-- Alignment Variants -->
<section style="margin-bottom: 3rem;">
<h3>Alignment</h3>
<div style="margin-bottom: 2rem;">
<h4>Left Aligned</h4>
<ui-pagination
[currentPage]="currentPageLeft"
[totalPages]="totalPagesDemo"
alignment="left"
(pageChange)="onPageChange($event, 'left')">
</ui-pagination>
</div>
<div style="margin-bottom: 2rem;">
<h4>Center Aligned (Default)</h4>
<ui-pagination
[currentPage]="currentPageCenter"
[totalPages]="totalPagesDemo"
alignment="center"
(pageChange)="onPageChange($event, 'center')">
</ui-pagination>
</div>
<div style="margin-bottom: 2rem;">
<h4>Right Aligned</h4>
<ui-pagination
[currentPage]="currentPageRight"
[totalPages]="totalPagesDemo"
alignment="right"
(pageChange)="onPageChange($event, 'right')">
</ui-pagination>
</div>
</section>
<!-- Page Info Variants -->
<section style="margin-bottom: 3rem;">
<h3>With Page Information</h3>
<div style="margin-bottom: 2rem;">
<h4>Basic Page Info</h4>
<ui-pagination
[currentPage]="currentPageInfo"
[totalPages]="totalPagesDemo"
[showInfo]="true"
(pageChange)="onPageChange($event, 'info')">
</ui-pagination>
</div>
<div style="margin-bottom: 2rem;">
<h4>With Items Count</h4>
<ui-pagination
[currentPage]="currentPageItems"
[totalPages]="totalPagesItems"
[totalItems]="totalItemsDemo"
[itemsPerPage]="itemsPerPageDemo"
[showInfo]="true"
(pageChange)="onPageChange($event, 'items')">
</ui-pagination>
</div>
<div style="margin-bottom: 2rem;">
<h4>Without Info</h4>
<ui-pagination
[currentPage]="currentPageNoInfo"
[totalPages]="totalPagesDemo"
[showInfo]="false"
(pageChange)="onPageChange($event, 'no-info')">
</ui-pagination>
</div>
</section>
<!-- Compact Variant -->
<section style="margin-bottom: 3rem;">
<h3>Compact Style</h3>
<div style="margin-bottom: 2rem;">
<h4>Compact Pagination</h4>
<ui-pagination
[currentPage]="currentPageCompact"
[totalPages]="totalPagesDemo"
[compact]="true"
(pageChange)="onPageChange($event, 'compact')">
</ui-pagination>
</div>
<div style="margin-bottom: 2rem;">
<h4>Compact with Labels</h4>
<ui-pagination
[currentPage]="currentPageCompactLabels"
[totalPages]="totalPagesDemo"
[compact]="true"
[showLabels]="true"
(pageChange)="onPageChange($event, 'compact-labels')">
</ui-pagination>
</div>
</section>
<!-- Different Page Counts -->
<section style="margin-bottom: 3rem;">
<h3>Different Page Counts</h3>
<div style="margin-bottom: 2rem;">
<h4>Few Pages (5 total)</h4>
<ui-pagination
[currentPage]="currentPageFew"
[totalPages]="totalPagesFew"
(pageChange)="onPageChange($event, 'few')">
</ui-pagination>
</div>
<div style="margin-bottom: 2rem;">
<h4>Many Pages (50 total)</h4>
<ui-pagination
[currentPage]="currentPageMany"
[totalPages]="totalPagesMany"
(pageChange)="onPageChange($event, 'many')">
</ui-pagination>
</div>
<div style="margin-bottom: 2rem;">
<h4>Limited Visible Pages (maxVisible=5)</h4>
<ui-pagination
[currentPage]="currentPageLimited"
[totalPages]="totalPagesMany"
[maxVisible]="5"
(pageChange)="onPageChange($event, 'limited')">
</ui-pagination>
</div>
</section>
<!-- Labels and States -->
<section style="margin-bottom: 3rem;">
<h3>Labels and States</h3>
<div style="margin-bottom: 2rem;">
<h4>With Navigation Labels</h4>
<ui-pagination
[currentPage]="currentPageLabels"
[totalPages]="totalPagesDemo"
[showLabels]="true"
previousLabel="Back"
nextLabel="Forward"
(pageChange)="onPageChange($event, 'labels')">
</ui-pagination>
</div>
<div style="margin-bottom: 2rem;">
<h4>Custom ARIA Labels</h4>
<ui-pagination
[currentPage]="currentPageAria"
[totalPages]="totalPagesDemo"
ariaLabel="Results pagination"
previousAriaLabel="Go to previous results page"
nextAriaLabel="Go to next results page"
(pageChange)="onPageChange($event, 'aria')">
</ui-pagination>
</div>
<div style="margin-bottom: 2rem;">
<h4>Disabled State</h4>
<ui-pagination
[currentPage]="currentPageDisabled"
[totalPages]="totalPagesDemo"
[disabled]="true"
(pageChange)="onPageChange($event, 'disabled')">
</ui-pagination>
</div>
</section>
<!-- Interactive Example -->
<section style="margin-bottom: 3rem;">
<h3>Interactive Pagination</h3>
<div style="margin-bottom: 2rem;">
<h4>Controlled Pagination</h4>
<div style="margin-bottom: 1rem; display: flex; gap: 1rem; align-items: center; flex-wrap: wrap;">
<button
style="padding: 0.5rem 1rem; border: 1px solid #ccc; border-radius: 4px; background: white; cursor: pointer;"
(click)="goToFirstPage()">
First Page
</button>
<button
style="padding: 0.5rem 1rem; border: 1px solid #ccc; border-radius: 4px; background: white; cursor: pointer;"
(click)="goToLastPage()">
Last Page
</button>
<button
style="padding: 0.5rem 1rem; border: 1px solid #ccc; border-radius: 4px; background: white; cursor: pointer;"
(click)="jumpToMiddle()">
Jump to Middle
</button>
<button
style="padding: 0.5rem 1rem; border: 1px solid #ccc; border-radius: 4px; background: white; cursor: pointer;"
(click)="resetInteractive()">
Reset
</button>
</div>
<ui-pagination
#interactivePagination
[currentPage]="currentPageInteractive"
[totalPages]="totalPagesInteractive"
[totalItems]="totalItemsInteractive()"
[itemsPerPage]="itemsPerPageDemo"
[showInfo]="true"
size="lg"
(pageChange)="onInteractivePageChange($event)">
</ui-pagination>
</div>
@if (lastPageChange) {
<div style="margin-top: 1rem; padding: 1rem; background: #e3f2fd; border-radius: 4px;">
<strong>Last page change:</strong> {{ lastPageChange }}
</div>
}
</section>
<!-- Usage Examples -->
<section style="margin-bottom: 3rem;">
<h3>Usage Examples</h3>
<div style="background: #f8f9fa; padding: 1.5rem; border-radius: 8px; border-left: 4px solid #007bff;">
<h4>Basic Pagination:</h4>
<pre style="background: #fff; padding: 1rem; border-radius: 4px; overflow-x: auto;"><code>&lt;ui-pagination
[currentPage]="currentPage"
[totalPages]="totalPages"
(pageChange)="onPageChange($event)"&gt;
&lt;/ui-pagination&gt;</code></pre>
<h4>With Item Information:</h4>
<pre style="background: #fff; padding: 1rem; border-radius: 4px; overflow-x: auto;"><code>&lt;ui-pagination
[currentPage]="currentPage"
[totalPages]="totalPages"
[totalItems]="totalItems"
[itemsPerPage]="itemsPerPage"
[showInfo]="true"
(pageChange)="onPageChange($event)"&gt;
&lt;/ui-pagination&gt;</code></pre>
<h4>Compact with Labels:</h4>
<pre style="background: #fff; padding: 1rem; border-radius: 4px; overflow-x: auto;"><code>&lt;ui-pagination
[currentPage]="currentPage"
[totalPages]="totalPages"
[compact]="true"
[showLabels]="true"
size="sm"
alignment="left"
previousLabel="Back"
nextLabel="Forward"
(pageChange)="onPageChange($event)"&gt;
&lt;/ui-pagination&gt;</code></pre>
<h4>Customized Pagination:</h4>
<pre style="background: #fff; padding: 1rem; border-radius: 4px; overflow-x: auto;"><code>&lt;ui-pagination
[currentPage]="currentPage"
[totalPages]="totalPages"
[maxVisible]="5"
size="lg"
alignment="center"
ariaLabel="Search results pagination"
[showInfo]="true"
(pageChange)="handlePageChange($event)"&gt;
&lt;/ui-pagination&gt;</code></pre>
</div>
</section>
<!-- Edge Cases -->
<section style="margin-bottom: 3rem;">
<h3>Edge Cases</h3>
<div style="margin-bottom: 2rem;">
<h4>Single Page</h4>
<ui-pagination
[currentPage]="currentPageOne"
[totalPages]="totalPagesOne"
(pageChange)="onPageChange($event, 'single')">
</ui-pagination>
</div>
<div style="margin-bottom: 2rem;">
<h4>Two Pages</h4>
<ui-pagination
[currentPage]="currentPageTwo"
[totalPages]="totalPagesTwo"
(pageChange)="onPageChange($event, 'two')">
</ui-pagination>
</div>
<div style="margin-bottom: 2rem;">
<h4>Large Dataset (1000+ pages)</h4>
<ui-pagination
[currentPage]="currentPageLargeDataset"
[totalPages]="totalPagesLargeDataset"
[totalItems]="24934"
[itemsPerPage]="20"
[showInfo]="true"
[maxVisible]="7"
(pageChange)="onPageChange($event, 'large-dataset')">
</ui-pagination>
</div>
</section>
</div>
`,
styles: [`
h2 {
color: hsl(279, 14%, 11%);
font-size: 2rem;
margin-bottom: 2rem;
border-bottom: 2px solid hsl(258, 100%, 47%);
padding-bottom: 0.5rem;
}
h3 {
color: hsl(279, 14%, 25%);
font-size: 1.5rem;
margin-bottom: 1rem;
}
h4 {
color: hsl(287, 12%, 35%);
font-size: 1.125rem;
margin-bottom: 0.75rem;
}
section {
border: 1px solid hsl(289, 14%, 90%);
border-radius: 8px;
padding: 1.5rem;
background: hsl(286, 20%, 99%);
}
pre {
font-size: 0.875rem;
line-height: 1.5;
margin: 0.5rem 0;
}
code {
font-family: 'JetBrains Mono', monospace;
color: #d63384;
}
button:hover {
background: #f0f0f0 !important;
}
button:active {
background: #e0e0e0 !important;
}
`]
})
export class PaginationDemoComponent {
// Size variants
currentPageSmall = signal(2);
currentPageMedium = signal(3);
currentPageLarge = signal(4);
// Alignment variants
currentPageLeft = signal(1);
currentPageCenter = signal(5);
currentPageRight = signal(8);
// Info variants
currentPageInfo = signal(3);
currentPageItems = signal(2);
currentPageNoInfo = signal(6);
// Compact variants
currentPageCompact = signal(4);
currentPageCompactLabels = signal(2);
// Different counts
currentPageFew = signal(3);
currentPageMany = signal(25);
currentPageLimited = signal(15);
// Labels and states
currentPageLabels = signal(1);
currentPageAria = signal(1);
currentPageDisabled = signal(5);
// Interactive
currentPageInteractive = signal(1);
totalPagesInteractive = signal(20);
totalItemsInteractive = signal(387);
// Edge cases
currentPageTwo = signal(1);
currentPageLargeDataset = signal(234);
// Constants for edge cases
totalPagesOne = signal(1);
currentPageOne = signal(1);
totalPagesTwo = signal(2);
totalPagesLargeDataset = signal(1247);
// Demo data
totalPagesDemo = signal(12);
totalPagesFew = signal(5);
totalPagesMany = signal(50);
totalItemsDemo = 234;
itemsPerPageDemo = 20;
totalPagesItems = signal(Math.ceil(this.totalItemsDemo / this.itemsPerPageDemo));
// Interactive state
lastPageChange: string = '';
onPageChange(event: any, type: string): void {
this.lastPageChange = `${type}: Page ${event.previousPage}${event.page}`;
console.log(`Page changed in ${type}:`, event);
// Update the appropriate signal based on type
switch (type) {
case 'small':
this.currentPageSmall.set(event.page);
break;
case 'medium':
this.currentPageMedium.set(event.page);
break;
case 'large':
this.currentPageLarge.set(event.page);
break;
case 'left':
this.currentPageLeft.set(event.page);
break;
case 'center':
this.currentPageCenter.set(event.page);
break;
case 'right':
this.currentPageRight.set(event.page);
break;
case 'info':
this.currentPageInfo.set(event.page);
break;
case 'items':
this.currentPageItems.set(event.page);
break;
case 'no-info':
this.currentPageNoInfo.set(event.page);
break;
case 'compact':
this.currentPageCompact.set(event.page);
break;
case 'compact-labels':
this.currentPageCompactLabels.set(event.page);
break;
case 'few':
this.currentPageFew.set(event.page);
break;
case 'many':
this.currentPageMany.set(event.page);
break;
case 'limited':
this.currentPageLimited.set(event.page);
break;
case 'labels':
this.currentPageLabels.set(event.page);
break;
case 'aria':
this.currentPageAria.set(event.page);
break;
case 'two':
this.currentPageTwo.set(event.page);
break;
case 'large-dataset':
this.currentPageLargeDataset.set(event.page);
break;
}
}
onInteractivePageChange(event: any): void {
this.currentPageInteractive.set(event.page);
this.lastPageChange = `Interactive: Page ${event.previousPage}${event.page}`;
}
// Interactive controls
goToFirstPage(): void {
this.currentPageInteractive.set(1);
this.lastPageChange = 'Programmatically navigated to first page';
}
goToLastPage(): void {
this.currentPageInteractive.set(this.totalPagesInteractive());
this.lastPageChange = 'Programmatically navigated to last page';
}
jumpToMiddle(): void {
const middle = Math.ceil(this.totalPagesInteractive() / 2);
this.currentPageInteractive.set(middle);
this.lastPageChange = `Programmatically jumped to middle page (${middle})`;
}
resetInteractive(): void {
this.currentPageInteractive.set(1);
this.lastPageChange = 'Interactive pagination reset';
}
}