This commit includes multiple new components and improvements to the UI essentials library: ## New Components Added: - **Accordion**: Expandable/collapsible content panels with full accessibility - **Alert**: Notification and messaging component with variants and dismiss functionality - **Popover**: Floating content containers with positioning and trigger options - **Timeline**: Chronological event display with customizable styling - **Tree View**: Hierarchical data display with expand/collapse functionality - **Toast**: Notification component (previously committed, includes style refinements) ## Component Features: - Full TypeScript implementation with Angular 19+ patterns - Comprehensive SCSS styling using semantic design tokens exclusively - Multiple size variants (sm, md, lg) and color variants (primary, success, warning, danger, info) - Accessibility support with ARIA attributes and keyboard navigation - Responsive design with mobile-first approach - Interactive demos showcasing all component features - Integration with existing design system and routing ## Demo Applications: - Created comprehensive demo components for each new component - Interactive examples with live code demonstrations - Integrated into main demo application routing and navigation ## Documentation: - Added COMPONENT_CREATION_TEMPLATE.md with detailed guidelines - Comprehensive component creation patterns and best practices - Design token usage guidelines and validation rules ## Code Quality: - Follows established Angular and SCSS conventions - Uses only verified semantic design tokens - Maintains consistency with existing component architecture - Comprehensive error handling and edge case management 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
212 lines
7.3 KiB
TypeScript
212 lines
7.3 KiB
TypeScript
import { Component } from '@angular/core';
|
|
import { CommonModule } from '@angular/common';
|
|
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
|
|
import { AlertComponent } from "../../../../../ui-essentials/src/public-api";
|
|
|
|
@Component({
|
|
selector: 'ui-alert-demo',
|
|
standalone: true,
|
|
imports: [CommonModule, FontAwesomeModule, AlertComponent],
|
|
template: `
|
|
<div class="demo-container">
|
|
<h2>Alert Demo</h2>
|
|
|
|
<!-- Size Variants -->
|
|
<section class="demo-section">
|
|
<h3>Sizes</h3>
|
|
<div class="demo-column">
|
|
@for (size of sizes; track size) {
|
|
<ui-alert [size]="size" title="{{size | titlecase}} Alert">
|
|
This is a {{ size }} size alert component demonstration.
|
|
</ui-alert>
|
|
}
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Variant Types -->
|
|
<section class="demo-section">
|
|
<h3>Variants</h3>
|
|
<div class="demo-column">
|
|
<ui-alert variant="primary" title="Primary Alert">
|
|
This is a primary alert for general information or neutral messages.
|
|
</ui-alert>
|
|
|
|
<ui-alert variant="success" title="Success Alert">
|
|
Your action was completed successfully! Everything worked as expected.
|
|
</ui-alert>
|
|
|
|
<ui-alert variant="warning" title="Warning Alert">
|
|
Please review this information carefully before proceeding.
|
|
</ui-alert>
|
|
|
|
<ui-alert variant="danger" title="Error Alert">
|
|
Something went wrong. Please check your input and try again.
|
|
</ui-alert>
|
|
|
|
<ui-alert variant="info" title="Information Alert">
|
|
Here's some helpful information you might want to know.
|
|
</ui-alert>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Without Icons -->
|
|
<section class="demo-section">
|
|
<h3>Without Icons</h3>
|
|
<div class="demo-column">
|
|
<ui-alert variant="success" title="Success" [showIcon]="false">
|
|
This alert doesn't show an icon for a cleaner look.
|
|
</ui-alert>
|
|
|
|
<ui-alert variant="warning" [showIcon]="false">
|
|
This warning alert has no title and no icon.
|
|
</ui-alert>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Dismissible Alerts -->
|
|
<section class="demo-section">
|
|
<h3>Dismissible Alerts</h3>
|
|
<div class="demo-column">
|
|
@for (dismissibleAlert of dismissibleAlerts; track dismissibleAlert.id) {
|
|
<ui-alert
|
|
[variant]="dismissibleAlert.variant"
|
|
[title]="dismissibleAlert.title"
|
|
[dismissible]="true"
|
|
(dismissed)="dismissAlert(dismissibleAlert.id)">
|
|
{{ dismissibleAlert.message }}
|
|
</ui-alert>
|
|
}
|
|
|
|
@if (dismissibleAlerts.length === 0) {
|
|
<p class="demo-message">All dismissible alerts have been dismissed. <button type="button" (click)="resetDismissibleAlerts()" class="demo-button">Reset Alerts</button></p>
|
|
}
|
|
</div>
|
|
</section>
|
|
|
|
<!-- No Title Alerts -->
|
|
<section class="demo-section">
|
|
<h3>Without Titles</h3>
|
|
<div class="demo-column">
|
|
<ui-alert variant="info">
|
|
This is an informational alert without a title. The message stands on its own.
|
|
</ui-alert>
|
|
|
|
<ui-alert variant="danger" [dismissible]="true">
|
|
This is a dismissible error alert without a title.
|
|
</ui-alert>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Bold Titles -->
|
|
<section class="demo-section">
|
|
<h3>Bold Titles</h3>
|
|
<div class="demo-column">
|
|
<ui-alert variant="primary" title="Important Notice" [boldTitle]="true">
|
|
This alert has a bold title to emphasize importance.
|
|
</ui-alert>
|
|
|
|
<ui-alert variant="warning" title="Critical Warning" [boldTitle]="true" [dismissible]="true">
|
|
Bold titles help draw attention to critical messages.
|
|
</ui-alert>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Interactive Examples -->
|
|
<section class="demo-section">
|
|
<h3>Interactive Examples</h3>
|
|
<div class="demo-column">
|
|
<ui-alert
|
|
variant="success"
|
|
title="Form Submitted Successfully"
|
|
[dismissible]="true"
|
|
(dismissed)="handleAlertDismissed('success')">
|
|
Your form has been submitted and will be processed within 24 hours.
|
|
</ui-alert>
|
|
|
|
<ui-alert
|
|
variant="info"
|
|
title="Newsletter Subscription"
|
|
[dismissible]="true"
|
|
(dismissed)="handleAlertDismissed('newsletter')">
|
|
Don't forget to confirm your email address to complete your subscription.
|
|
</ui-alert>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- All Combinations -->
|
|
<section class="demo-section">
|
|
<h3>Size & Variant Combinations</h3>
|
|
<div class="demo-grid">
|
|
@for (variant of variants; track variant) {
|
|
<div class="demo-variant-group">
|
|
<h4>{{ variant | titlecase }}</h4>
|
|
@for (size of sizes; track size) {
|
|
<ui-alert
|
|
[variant]="variant"
|
|
[size]="size"
|
|
[title]="size | titlecase"
|
|
[dismissible]="size === 'lg'">
|
|
{{ variant | titlecase }} {{ size }} alert
|
|
</ui-alert>
|
|
}
|
|
</div>
|
|
}
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Accessibility Information -->
|
|
<section class="demo-section">
|
|
<h3>Accessibility Features</h3>
|
|
<div class="demo-info">
|
|
<ul>
|
|
<li><strong>Screen Reader Support:</strong> Proper ARIA labels and live regions</li>
|
|
<li><strong>Keyboard Navigation:</strong> Dismissible alerts can be closed with Enter or Space</li>
|
|
<li><strong>Focus Management:</strong> Clear focus indicators on dismiss button</li>
|
|
<li><strong>Semantic HTML:</strong> Proper heading hierarchy and content structure</li>
|
|
</ul>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
`,
|
|
styleUrl: './alert-demo.component.scss'
|
|
})
|
|
export class AlertDemoComponent {
|
|
sizes = ['sm', 'md', 'lg'] as const;
|
|
variants = ['primary', 'success', 'warning', 'danger', 'info'] as const;
|
|
|
|
dismissibleAlerts = [
|
|
{
|
|
id: 1,
|
|
variant: 'success' as const,
|
|
title: 'Task Completed',
|
|
message: 'Your task has been completed successfully and saved to your dashboard.'
|
|
},
|
|
{
|
|
id: 2,
|
|
variant: 'warning' as const,
|
|
title: 'Session Expiring',
|
|
message: 'Your session will expire in 5 minutes. Please save your work.'
|
|
},
|
|
{
|
|
id: 3,
|
|
variant: 'info' as const,
|
|
title: 'New Feature Available',
|
|
message: 'Check out our new dashboard analytics feature in the sidebar menu.'
|
|
}
|
|
];
|
|
|
|
private originalDismissibleAlerts = [...this.dismissibleAlerts];
|
|
|
|
dismissAlert(id: number): void {
|
|
this.dismissibleAlerts = this.dismissibleAlerts.filter(alert => alert.id !== id);
|
|
console.log(`Alert with ID ${id} dismissed`);
|
|
}
|
|
|
|
resetDismissibleAlerts(): void {
|
|
this.dismissibleAlerts = [...this.originalDismissibleAlerts];
|
|
}
|
|
|
|
handleAlertDismissed(type: string): void {
|
|
console.log(`${type} alert dismissed`);
|
|
}
|
|
} |