import { Component, ChangeDetectionStrategy, signal } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ListItemComponent, ListContainerComponent, ListItemData } from '../../../../../ui-essentials/src/lib/components/data-display/list'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { faInbox, faStar, faPaperPlane, faEdit, faArchive, faTrash, faPhone, faComment, faPlay, faDownload, faCheck, faChevronRight, faPlus, faMinus } from '@fortawesome/free-solid-svg-icons'; @Component({ selector: 'ui-list-demo', standalone: true, imports: [ CommonModule, ListItemComponent, ListContainerComponent, FontAwesomeModule ], changeDetection: ChangeDetectionStrategy.OnPush, template: `

List Component Showcase

Basic Lists - Size Variants

Small (sm)

@for (item of navigationItems; track item.primary) { }

Medium (md)

@for (item of navigationItems; track item.primary) { }

Large (lg)

@for (item of navigationItems; track item.primary) { }

Multi-line Lists

Two Lines

@for (item of twoLineItems; track item.primary) { }

Three Lines

@for (item of threeLineItems; track item.primary) {
}

Lists with Avatars

Contacts - Avatar + One Line

@for (item of contactItems; track item.primary) {
}

Messages - Avatar + Two Lines

@for (item of messageItems; track item.primary) { 2h }

Lists with Media

Music - Media + Two Lines

@for (item of musicItems; track item.primary) {
3:42
}

Videos - Media + Three Lines

@for (item of videoItems; track item.primary) {
4.8
}

Interactive Demo

Click items to interact with them:

@for (item of interactiveItems(); track item.primary) {
@if (item.selected) { Enabled } @else if (item.disabled) { Disabled } @else { Click to enable }
}

Usage Examples

Basic List with Icons:

<ui-list-container elevation="sm" spacing="xs" [rounded]="true">
  <ui-list-item 
    [data]="{primary: 'Inbox'}"
    size="md"
    lines="one"
    variant="text">
    <fa-icon [icon]="faInbox" slot="trailing"></fa-icon>
  </ui-list-item>
</ui-list-container>

List with Avatar and Actions:

<ui-list-container elevation="md" spacing="sm" [rounded]="true">
  <ui-list-item 
    [data]="{
      primary: 'John Doe',
      secondary: 'john@example.com',
      avatarSrc: 'avatar.jpg'
    }"
    size="lg"
    lines="two"
    variant="avatar">
    <button slot="trailing" (click)="call()">
      <fa-icon [icon]="faPhone"></fa-icon>
    </button>
  </ui-list-item>
</ui-list-container>
@if (lastAction()) {
Action: {{ lastAction() }}
}
`, 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; margin-top: 2rem; } h4 { color: hsl(287, 12%, 35%); font-size: 1.125rem; margin-bottom: 0.75rem; margin-top: 1rem; } section { border: 1px solid hsl(289, 14%, 90%); border-radius: 12px; padding: 1.5rem; background: hsl(286, 20%, 99%); margin-bottom: 2rem; } pre { font-size: 0.875rem; line-height: 1.5; margin: 0.5rem 0; white-space: pre-wrap; } code { font-family: 'JetBrains Mono', 'Fira Code', 'Monaco', 'Courier New', monospace; color: #d63384; } button { transition: all 0.15s ease; } button:hover { transform: translateY(-1px); } button:active { transform: translateY(0); } fa-icon { transition: color 0.2s ease; } `] }) export class ListDemoComponent { // State signals lastAction = signal(''); // Demo data navigationItems: ListItemData[] = [ { primary: 'Inbox' }, { primary: 'Starred' }, { primary: 'Sent' }, { primary: 'Drafts' }, { primary: 'Archive' }, { primary: 'Trash' } ]; twoLineItems: ListItemData[] = [ { primary: 'Review Design System Updates', secondary: 'Check new component specifications and design tokens' }, { primary: 'Team Standup Meeting', secondary: 'Daily sync with development and design teams' }, { primary: 'Code Review - Authentication', secondary: 'Review pull request #247 for OAuth integration' } ]; threeLineItems: ListItemData[] = [ { primary: 'Angular 19 Migration', secondary: 'Upgrade project to latest Angular version with control flow', tertiary: 'Estimated completion: Next Sprint • Priority: High' }, { primary: 'Design System Documentation', secondary: 'Create comprehensive documentation for all components', tertiary: 'Status: In Progress • Assigned: Design Team' } ]; contactItems: ListItemData[] = [ { primary: 'Sarah Wilson', avatarSrc: 'https://api.dicebear.com/7.x/avataaars/svg?seed=sarah', avatarAlt: 'Sarah Wilson avatar' }, { primary: 'Alex Chen', avatarSrc: 'https://api.dicebear.com/7.x/avataaars/svg?seed=alex', avatarAlt: 'Alex Chen avatar' }, { primary: 'Mike Rodriguez', avatarSrc: 'https://api.dicebear.com/7.x/avataaars/svg?seed=mike', avatarAlt: 'Mike Rodriguez avatar' } ]; messageItems: ListItemData[] = [ { primary: 'John Doe', secondary: 'Hey! How\'s the new component library coming along?', avatarSrc: 'https://api.dicebear.com/7.x/avataaars/svg?seed=john', avatarAlt: 'John Doe avatar' }, { primary: 'Jane Smith', secondary: 'The design tokens look great. Ready for review when you are.', avatarSrc: 'https://api.dicebear.com/7.x/avataaars/svg?seed=jane', avatarAlt: 'Jane Smith avatar' } ]; musicItems: ListItemData[] = [ { primary: 'Bohemian Rhapsody', secondary: 'Queen • A Night at the Opera', mediaSrc: 'https://picsum.photos/80/80?random=1', mediaAlt: 'Album cover' }, { primary: 'Hotel California', secondary: 'Eagles • Hotel California', mediaSrc: 'https://picsum.photos/80/80?random=2', mediaAlt: 'Album cover' } ]; videoItems: ListItemData[] = [ { primary: 'Angular Fundamentals', secondary: 'Complete guide to modern Angular development', tertiary: 'Duration: 2h 30m • Updated: Today • 1.2M views', mediaSrc: 'https://picsum.photos/80/80?random=5', mediaAlt: 'Video thumbnail' } ]; interactiveItems = signal([ { primary: 'Email Notifications', secondary: 'Receive emails about important updates', avatarSrc: 'https://api.dicebear.com/7.x/avataaars/svg?seed=email', selected: false, disabled: false }, { primary: 'SMS Alerts', secondary: 'Get text messages for urgent notifications', avatarSrc: 'https://api.dicebear.com/7.x/avataaars/svg?seed=sms', selected: true, disabled: false }, { primary: 'Marketing Communications', secondary: 'Promotional offers and product updates', avatarSrc: 'https://api.dicebear.com/7.x/avataaars/svg?seed=marketing', selected: false, disabled: true } ]); // Font Awesome icons faInbox = faInbox; faStar = faStar; faPaperPlane = faPaperPlane; faEdit = faEdit; faArchive = faArchive; faTrash = faTrash; faPhone = faPhone; faComment = faComment; faPlay = faPlay; faDownload = faDownload; faCheck = faCheck; faChevronRight = faChevronRight; faPlus = faPlus; faMinus = faMinus; // Helper methods getIconForItem(itemName: string): any { const iconMap: { [key: string]: any } = { 'Inbox': faInbox, 'Starred': faStar, 'Sent': faPaperPlane, 'Drafts': faEdit, 'Archive': faArchive, 'Trash': faTrash }; return iconMap[itemName] || faInbox; } // Event handlers handleAction(action: string, item?: string): void { const message = item ? `${action} action on "${item}" at ${new Date().toLocaleTimeString()}` : `${action} action at ${new Date().toLocaleTimeString()}`; this.lastAction.set(message); console.log(`List action: ${action}`, item); // Clear the message after 3 seconds setTimeout(() => this.lastAction.set(''), 3000); } toggleInteractiveItem(itemName: string): void { this.interactiveItems.update(items => items.map(item => { if (item.primary === itemName && !item.disabled) { return { ...item, selected: !item.selected }; } return item; }) ); this.handleAction('toggle', itemName); } }