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:
@@ -0,0 +1,132 @@
|
||||
import { Component, EventEmitter, Output, Input, OnInit } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
|
||||
import { MenuItemComponent } from '../../../../../ui-essentials/src/lib/components/navigation/menu';
|
||||
import { faChevronRight, faChevronDown } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
export interface SidebarMenuItem {
|
||||
id: string;
|
||||
label: string;
|
||||
icon?: any; // FontAwesome icon definition
|
||||
active: boolean;
|
||||
children?: SidebarMenuItem[];
|
||||
expanded?: boolean;
|
||||
isParent?: boolean;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'skyui-dashboard-sidebar',
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
FontAwesomeModule,
|
||||
MenuItemComponent
|
||||
],
|
||||
template: `
|
||||
<div class="sidebar-container">
|
||||
@for(item of data; track item.id) {
|
||||
<div class="menu-item-wrapper">
|
||||
@if(item.isParent) {
|
||||
<div class="parent-menu-item" (click)="toggleExpanded(item)">
|
||||
<div class="parent-content">
|
||||
<fa-icon [icon]="item.icon" class="parent-icon"></fa-icon>
|
||||
<span class="parent-label">{{ item.label }}</span>
|
||||
</div>
|
||||
<fa-icon
|
||||
[icon]="item.expanded ? faChevronDown : faChevronRight"
|
||||
class="chevron-icon">
|
||||
</fa-icon>
|
||||
</div>
|
||||
@if(item.expanded && item.children) {
|
||||
<div class="children-container">
|
||||
@for(child of item.children; track child.id) {
|
||||
<ui-menu-item
|
||||
[data]="{ label: child.label, icon: child.icon, active: child.active }"
|
||||
[size]="'md'"
|
||||
iconPosition="left"
|
||||
(itemClick)="handleMenuClick(child.id)"
|
||||
class="child-menu-item"
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
} @else {
|
||||
<ui-menu-item
|
||||
[data]="{ label: item.label, icon: item.icon, active: item.active }"
|
||||
[size]="'md'"
|
||||
iconPosition="left"
|
||||
(itemClick)="handleMenuClick(item.id)"
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
`,
|
||||
styleUrls: ['./dashboard.sidebar.component.scss']
|
||||
|
||||
})
|
||||
export class DashboardSidebarComponent implements OnInit {
|
||||
|
||||
@Input() data: SidebarMenuItem[] = [];
|
||||
@Input() set active(value: string) { this.setActive(value) }
|
||||
@Output() selected = new EventEmitter<string>();
|
||||
|
||||
faChevronRight = faChevronRight;
|
||||
faChevronDown = faChevronDown;
|
||||
|
||||
handleMenuClick(id: string): void {
|
||||
this.setActive(id);
|
||||
this.selected.emit(id);
|
||||
}
|
||||
|
||||
setActive(id: string): void {
|
||||
this.setActiveRecursive(this.data, id);
|
||||
}
|
||||
|
||||
private setActiveRecursive(items: SidebarMenuItem[], id: string): void {
|
||||
items.forEach(item => {
|
||||
item.active = item.id === id;
|
||||
if (item.children) {
|
||||
this.setActiveRecursive(item.children, id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getActiveMenuItem(): SidebarMenuItem | undefined {
|
||||
return this.getActiveMenuItemRecursive(this.data);
|
||||
}
|
||||
|
||||
private getActiveMenuItemRecursive(items: SidebarMenuItem[]): SidebarMenuItem | undefined {
|
||||
for (const item of items) {
|
||||
if (item.active) return item;
|
||||
if (item.children) {
|
||||
const found = this.getActiveMenuItemRecursive(item.children);
|
||||
if (found) return found;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
clearSelection(): void {
|
||||
this.clearSelectionRecursive(this.data);
|
||||
}
|
||||
|
||||
private clearSelectionRecursive(items: SidebarMenuItem[]): void {
|
||||
items.forEach(item => {
|
||||
item.active = false;
|
||||
if (item.children) {
|
||||
this.clearSelectionRecursive(item.children);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
toggleExpanded(item: SidebarMenuItem): void {
|
||||
if (item.isParent) {
|
||||
item.expanded = !item.expanded;
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user