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,588 @@
|
||||
import { Component, ChangeDetectionStrategy, signal } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { AppbarComponent } from '../../../../../ui-essentials/src/lib/components/navigation/appbar';
|
||||
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
|
||||
import {
|
||||
faBars,
|
||||
faSearch,
|
||||
faUser,
|
||||
faHeart,
|
||||
faBell,
|
||||
faCog,
|
||||
faShoppingCart,
|
||||
faHome,
|
||||
faArrowLeft,
|
||||
faPlus,
|
||||
faShare,
|
||||
faEllipsisV,
|
||||
faSun,
|
||||
faMoon
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-appbar-demo',
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
AppbarComponent,
|
||||
FontAwesomeModule
|
||||
],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
template: `
|
||||
<div style="padding: 2rem;">
|
||||
<h2>Appbar Component Showcase</h2>
|
||||
|
||||
<!-- Appbar Variants -->
|
||||
<section style="margin-bottom: 3rem;">
|
||||
<h3>Appbar Variants</h3>
|
||||
|
||||
<div style="margin-bottom: 2rem;">
|
||||
<h4>Compact</h4>
|
||||
<div style="border: 1px solid #e9ecef; border-radius: 8px; overflow: hidden; margin-bottom: 1rem;">
|
||||
<ui-appbar
|
||||
variant="compact"
|
||||
[slots]="{title: true, leftIcon: true, rightIcon: true}"
|
||||
[elevated]="false">
|
||||
<fa-icon [icon]="faBars" slot="left-icon"></fa-icon>
|
||||
<span slot="title">Compact Appbar</span>
|
||||
<fa-icon [icon]="faSearch" slot="right-icon"></fa-icon>
|
||||
</ui-appbar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 2rem;">
|
||||
<h4>Standard</h4>
|
||||
<div style="border: 1px solid #e9ecef; border-radius: 8px; overflow: hidden; margin-bottom: 1rem;">
|
||||
<ui-appbar
|
||||
variant="standard"
|
||||
[slots]="{title: true, leftIcon: true, rightAvatar: true}"
|
||||
[elevated]="false">
|
||||
<fa-icon [icon]="faBars" slot="left-icon"></fa-icon>
|
||||
<span slot="title">Standard Appbar</span>
|
||||
<div slot="right-avatar" style="width: 32px; height: 32px; border-radius: 50%; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); display: flex; align-items: center; justify-content: center; color: white; font-weight: 500;">
|
||||
JS
|
||||
</div>
|
||||
</ui-appbar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 2rem;">
|
||||
<h4>Large</h4>
|
||||
<div style="border: 1px solid #e9ecef; border-radius: 8px; overflow: hidden; margin-bottom: 1rem;">
|
||||
<ui-appbar
|
||||
variant="large"
|
||||
[slots]="{title: true, leftIcon: true, rightMenu: true}"
|
||||
[elevated]="false">
|
||||
<fa-icon [icon]="faArrowLeft" slot="left-icon"></fa-icon>
|
||||
<span slot="title">Large Appbar with More Space</span>
|
||||
<div slot="right-menu" style="display: flex; gap: 1rem;">
|
||||
<fa-icon [icon]="faHeart" style="cursor: pointer;"></fa-icon>
|
||||
<fa-icon [icon]="faShare" style="cursor: pointer;"></fa-icon>
|
||||
<fa-icon [icon]="faEllipsisV" style="cursor: pointer;"></fa-icon>
|
||||
</div>
|
||||
</ui-appbar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 2rem;">
|
||||
<h4>Prominent</h4>
|
||||
<div style="border: 1px solid #e9ecef; border-radius: 8px; overflow: hidden; margin-bottom: 1rem;">
|
||||
<ui-appbar
|
||||
variant="prominent"
|
||||
[slots]="{title: true, leftLogo: true, rightIcon: true}"
|
||||
[elevated]="false">
|
||||
<div slot="left-logo" style="display: flex; align-items: center; gap: 0.5rem; font-weight: 600; color: #007bff;">
|
||||
<div style="width: 24px; height: 24px; background: linear-gradient(135deg, #007bff, #0056b3); border-radius: 4px;"></div>
|
||||
SkyUI
|
||||
</div>
|
||||
<span slot="title">Prominent Design System</span>
|
||||
<fa-icon [icon]="faCog" slot="right-icon"></fa-icon>
|
||||
</ui-appbar>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Elevation and Position -->
|
||||
<section style="margin-bottom: 3rem;">
|
||||
<h3>Elevation & Position</h3>
|
||||
|
||||
<div style="margin-bottom: 2rem;">
|
||||
<h4>Elevated</h4>
|
||||
<div style="border: 1px solid #e9ecef; border-radius: 8px; overflow: hidden; margin-bottom: 1rem;">
|
||||
<ui-appbar
|
||||
variant="standard"
|
||||
[slots]="{title: true, leftIcon: true, rightIcon: true}"
|
||||
[elevated]="true">
|
||||
<fa-icon [icon]="faBars" slot="left-icon"></fa-icon>
|
||||
<span slot="title">Elevated Appbar</span>
|
||||
<fa-icon [icon]="faBell" slot="right-icon"></fa-icon>
|
||||
</ui-appbar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 2rem;">
|
||||
<h4>Not Elevated</h4>
|
||||
<div style="border: 1px solid #e9ecef; border-radius: 8px; overflow: hidden; margin-bottom: 1rem;">
|
||||
<ui-appbar
|
||||
variant="standard"
|
||||
[slots]="{title: true, leftIcon: true, rightIcon: true}"
|
||||
[elevated]="false">
|
||||
<fa-icon [icon]="faBars" slot="left-icon"></fa-icon>
|
||||
<span slot="title">Flat Appbar</span>
|
||||
<fa-icon [icon]="faBell" slot="right-icon"></fa-icon>
|
||||
</ui-appbar>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Slot Configurations -->
|
||||
<section style="margin-bottom: 3rem;">
|
||||
<h3>Slot Configurations</h3>
|
||||
|
||||
<div style="margin-bottom: 2rem;">
|
||||
<h4>Left Icon + Title + Right Avatar</h4>
|
||||
<div style="border: 1px solid #e9ecef; border-radius: 8px; overflow: hidden; margin-bottom: 1rem;">
|
||||
<ui-appbar
|
||||
variant="standard"
|
||||
[slots]="{title: true, leftIcon: true, rightAvatar: true}">
|
||||
<fa-icon [icon]="faHome" slot="left-icon"></fa-icon>
|
||||
<span slot="title">Home</span>
|
||||
<img
|
||||
slot="right-avatar"
|
||||
src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=32&h=32&fit=crop&crop=face"
|
||||
style="width: 32px; height: 32px; border-radius: 50%; object-fit: cover;"
|
||||
alt="User avatar"
|
||||
(error)="handleImageError($event)">
|
||||
</ui-appbar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 2rem;">
|
||||
<h4>Left Logo + Title + Right Menu</h4>
|
||||
<div style="border: 1px solid #e9ecef; border-radius: 8px; overflow: hidden; margin-bottom: 1rem;">
|
||||
<ui-appbar
|
||||
variant="standard"
|
||||
[slots]="{title: true, leftLogo: true, rightMenu: true}">
|
||||
<div slot="left-logo" style="display: flex; align-items: center; gap: 0.5rem; font-weight: 600;">
|
||||
<div style="width: 20px; height: 20px; background: linear-gradient(45deg, #ff6b6b, #ee5a24); border-radius: 50%;"></div>
|
||||
App
|
||||
</div>
|
||||
<span slot="title">Dashboard</span>
|
||||
<div slot="right-menu" style="display: flex; gap: 1rem; align-items: center;">
|
||||
<fa-icon [icon]="faShoppingCart" style="cursor: pointer;" (click)="handleAction('cart')"></fa-icon>
|
||||
<fa-icon [icon]="faBell" style="cursor: pointer;" (click)="handleAction('notifications')"></fa-icon>
|
||||
<fa-icon [icon]="faUser" style="cursor: pointer;" (click)="handleAction('profile')"></fa-icon>
|
||||
</div>
|
||||
</ui-appbar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 2rem;">
|
||||
<h4>Left Avatar + Title + Right Icon</h4>
|
||||
<div style="border: 1px solid #e9ecef; border-radius: 8px; overflow: hidden; margin-bottom: 1rem;">
|
||||
<ui-appbar
|
||||
variant="standard"
|
||||
[slots]="{title: true, leftAvatar: true, rightIcon: true}">
|
||||
<div slot="left-avatar" style="width: 32px; height: 32px; border-radius: 50%; background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%); display: flex; align-items: center; justify-content: center; color: #333; font-weight: 500; font-size: 12px;">
|
||||
UI
|
||||
</div>
|
||||
<span slot="title">Profile Settings</span>
|
||||
<button
|
||||
slot="right-icon"
|
||||
style="background: none; border: none; padding: 8px; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center;"
|
||||
(click)="toggleTheme()">
|
||||
<fa-icon [icon]="isDarkMode() ? faSun : faMoon"></fa-icon>
|
||||
</button>
|
||||
</ui-appbar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 2rem;">
|
||||
<h4>Multiple Right Elements</h4>
|
||||
<div style="border: 1px solid #e9ecef; border-radius: 8px; overflow: hidden; margin-bottom: 1rem;">
|
||||
<ui-appbar
|
||||
variant="standard"
|
||||
[slots]="{title: true, leftIcon: true, rightIcon: true, rightMenu: true}">
|
||||
<fa-icon [icon]="faBars" slot="left-icon"></fa-icon>
|
||||
<span slot="title">Multi-Action Bar</span>
|
||||
<fa-icon [icon]="faPlus" slot="right-icon" style="cursor: pointer;" (click)="handleAction('add')"></fa-icon>
|
||||
<div slot="right-menu" style="display: flex; gap: 0.5rem;">
|
||||
<fa-icon [icon]="faSearch" style="cursor: pointer;" (click)="handleAction('search')"></fa-icon>
|
||||
<fa-icon [icon]="faEllipsisV" style="cursor: pointer;" (click)="handleAction('more')"></fa-icon>
|
||||
</div>
|
||||
</ui-appbar>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Real-world Examples -->
|
||||
<section style="margin-bottom: 3rem;">
|
||||
<h3>Real-world Examples</h3>
|
||||
|
||||
<div style="margin-bottom: 2rem;">
|
||||
<h4>E-commerce App</h4>
|
||||
<div style="border: 1px solid #e9ecef; border-radius: 8px; overflow: hidden; margin-bottom: 1rem;">
|
||||
<ui-appbar
|
||||
variant="standard"
|
||||
[slots]="{title: true, leftIcon: true, rightMenu: true}"
|
||||
[elevated]="true">
|
||||
<fa-icon [icon]="faBars" slot="left-icon"></fa-icon>
|
||||
<span slot="title">ShopMart</span>
|
||||
<div slot="right-menu" style="display: flex; gap: 1rem; align-items: center;">
|
||||
<div style="position: relative;">
|
||||
<fa-icon [icon]="faShoppingCart" style="cursor: pointer;" (click)="handleAction('cart')"></fa-icon>
|
||||
<span style="position: absolute; top: -8px; right: -8px; background: #ff4757; color: white; border-radius: 50%; width: 16px; height: 16px; display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: 600;">3</span>
|
||||
</div>
|
||||
<fa-icon [icon]="faSearch" style="cursor: pointer;" (click)="handleAction('search')"></fa-icon>
|
||||
</div>
|
||||
</ui-appbar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 2rem;">
|
||||
<h4>Social Media App</h4>
|
||||
<div style="border: 1px solid #e9ecef; border-radius: 8px; overflow: hidden; margin-bottom: 1rem;">
|
||||
<ui-appbar
|
||||
variant="standard"
|
||||
[slots]="{title: true, leftLogo: true, rightMenu: true}"
|
||||
[elevated]="false">
|
||||
<div slot="left-logo" style="font-weight: 700; font-size: 1.25rem; background: linear-gradient(45deg, #667eea, #764ba2); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;">
|
||||
SocialHub
|
||||
</div>
|
||||
<span slot="title">Feed</span>
|
||||
<div slot="right-menu" style="display: flex; gap: 1rem; align-items: center;">
|
||||
<div style="position: relative;">
|
||||
<fa-icon [icon]="faBell" style="cursor: pointer;" (click)="handleAction('notifications')"></fa-icon>
|
||||
<span style="position: absolute; top: -6px; right: -6px; background: #ff3742; width: 8px; height: 8px; border-radius: 50%;"></span>
|
||||
</div>
|
||||
<fa-icon [icon]="faUser" style="cursor: pointer;" (click)="handleAction('profile')"></fa-icon>
|
||||
</div>
|
||||
</ui-appbar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 2rem;">
|
||||
<h4>Settings Page</h4>
|
||||
<div style="border: 1px solid #e9ecef; border-radius: 8px; overflow: hidden; margin-bottom: 1rem;">
|
||||
<ui-appbar
|
||||
variant="large"
|
||||
[slots]="{title: true, leftIcon: true, rightIcon: true}"
|
||||
[elevated]="false">
|
||||
<fa-icon [icon]="faArrowLeft" slot="left-icon" style="cursor: pointer;" (click)="handleAction('back')"></fa-icon>
|
||||
<span slot="title">Account Settings</span>
|
||||
<fa-icon [icon]="faCog" slot="right-icon" style="cursor: pointer;" (click)="handleAction('settings')"></fa-icon>
|
||||
</ui-appbar>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Interactive Demo -->
|
||||
<section style="margin-bottom: 3rem;">
|
||||
<h3>Interactive Demo</h3>
|
||||
<p style="margin-bottom: 1rem; color: #6c757d;">
|
||||
Customize the appbar below by toggling different options:
|
||||
</p>
|
||||
|
||||
<div style="display: flex; gap: 1rem; margin-bottom: 1rem; flex-wrap: wrap;">
|
||||
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
|
||||
<input
|
||||
type="checkbox"
|
||||
[checked]="demoConfig().elevated"
|
||||
(change)="updateDemoConfig('elevated', $event)">
|
||||
Elevated
|
||||
</label>
|
||||
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
|
||||
<input
|
||||
type="checkbox"
|
||||
[checked]="demoConfig().slots.leftIcon"
|
||||
(change)="updateDemoSlot('leftIcon', $event)">
|
||||
Left Icon
|
||||
</label>
|
||||
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
|
||||
<input
|
||||
type="checkbox"
|
||||
[checked]="demoConfig().slots.leftLogo"
|
||||
(change)="updateDemoSlot('leftLogo', $event)">
|
||||
Left Logo
|
||||
</label>
|
||||
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
|
||||
<input
|
||||
type="checkbox"
|
||||
[checked]="demoConfig().slots.rightIcon"
|
||||
(change)="updateDemoSlot('rightIcon', $event)">
|
||||
Right Icon
|
||||
</label>
|
||||
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
|
||||
<input
|
||||
type="checkbox"
|
||||
[checked]="demoConfig().slots.rightAvatar"
|
||||
(change)="updateDemoSlot('rightAvatar', $event)">
|
||||
Right Avatar
|
||||
</label>
|
||||
<label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
|
||||
<input
|
||||
type="checkbox"
|
||||
[checked]="demoConfig().slots.rightMenu"
|
||||
(change)="updateDemoSlot('rightMenu', $event)">
|
||||
Right Menu
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<label style="display: flex; align-items: center; gap: 0.5rem;">
|
||||
Variant:
|
||||
<select
|
||||
[value]="demoConfig().variant"
|
||||
(change)="updateDemoVariant($event)"
|
||||
style="padding: 0.25rem 0.5rem; border: 1px solid #ced4da; border-radius: 4px;">
|
||||
<option value="compact">Compact</option>
|
||||
<option value="standard">Standard</option>
|
||||
<option value="large">Large</option>
|
||||
<option value="prominent">Prominent</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div style="border: 1px solid #e9ecef; border-radius: 8px; overflow: hidden; margin-bottom: 1rem;">
|
||||
<ui-appbar
|
||||
[variant]="demoConfig().variant"
|
||||
[slots]="demoConfig().slots"
|
||||
[elevated]="demoConfig().elevated">
|
||||
@if (demoConfig().slots.leftIcon) {
|
||||
<fa-icon [icon]="faBars" slot="left-icon"></fa-icon>
|
||||
}
|
||||
@if (demoConfig().slots.leftLogo) {
|
||||
<div slot="left-logo" style="display: flex; align-items: center; gap: 0.5rem; font-weight: 600; color: #007bff;">
|
||||
<div style="width: 20px; height: 20px; background: linear-gradient(135deg, #007bff, #0056b3); border-radius: 4px;"></div>
|
||||
Demo
|
||||
</div>
|
||||
}
|
||||
<span slot="title">{{ demoConfig().title }}</span>
|
||||
@if (demoConfig().slots.rightIcon) {
|
||||
<fa-icon [icon]="faSearch" slot="right-icon"></fa-icon>
|
||||
}
|
||||
@if (demoConfig().slots.rightAvatar) {
|
||||
<div slot="right-avatar" style="width: 32px; height: 32px; border-radius: 50%; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); display: flex; align-items: center; justify-content: center; color: white; font-weight: 500; font-size: 12px;">
|
||||
DU
|
||||
</div>
|
||||
}
|
||||
@if (demoConfig().slots.rightMenu) {
|
||||
<div slot="right-menu" style="display: flex; gap: 1rem;">
|
||||
<fa-icon [icon]="faHeart" style="cursor: pointer;"></fa-icon>
|
||||
<fa-icon [icon]="faCog" style="cursor: pointer;"></fa-icon>
|
||||
</div>
|
||||
}
|
||||
</ui-appbar>
|
||||
</div>
|
||||
|
||||
@if (lastAction()) {
|
||||
<div style="padding: 1rem; background: #e3f2fd; border-radius: 4px;">
|
||||
<strong>Last action:</strong> {{ lastAction() }}
|
||||
</div>
|
||||
}
|
||||
</section>
|
||||
|
||||
<!-- Usage Examples -->
|
||||
<section style="margin-bottom: 3rem;">
|
||||
<h3>Code Examples</h3>
|
||||
<div style="background: #f8f9fa; padding: 1.5rem; border-radius: 8px; border-left: 4px solid #007bff;">
|
||||
<h4>Basic Appbar:</h4>
|
||||
<pre style="background: #fff; padding: 1rem; border-radius: 4px; overflow-x: auto;"><code><ui-appbar
|
||||
variant="standard"
|
||||
[slots]="{title: true, leftIcon: true, rightIcon: true}"
|
||||
[elevated]="false">
|
||||
<fa-icon [icon]="faBars" slot="left-icon"></fa-icon>
|
||||
<span slot="title">My App</span>
|
||||
<fa-icon [icon]="faSearch" slot="right-icon"></fa-icon>
|
||||
</ui-appbar></code></pre>
|
||||
|
||||
<h4>Appbar with Logo and Avatar:</h4>
|
||||
<pre style="background: #fff; padding: 1rem; border-radius: 4px; overflow-x: auto;"><code><ui-appbar
|
||||
variant="standard"
|
||||
[slots]="{title: true, leftLogo: true, rightAvatar: true}"
|
||||
[elevated]="true">
|
||||
<div slot="left-logo" style="font-weight: 600;">
|
||||
MyBrand
|
||||
</div>
|
||||
<span slot="title">Dashboard</span>
|
||||
<img slot="right-avatar" src="avatar.jpg"
|
||||
style="width: 32px; height: 32px; border-radius: 50%;">
|
||||
</ui-appbar></code></pre>
|
||||
|
||||
<h4>Appbar with Multiple Actions:</h4>
|
||||
<pre style="background: #fff; padding: 1rem; border-radius: 4px; overflow-x: auto;"><code><ui-appbar
|
||||
variant="standard"
|
||||
[slots]="{title: true, leftIcon: true, rightMenu: true}"
|
||||
[elevated]="false">
|
||||
<fa-icon [icon]="faArrowLeft" slot="left-icon"></fa-icon>
|
||||
<span slot="title">Settings</span>
|
||||
<div slot="right-menu" style="display: flex; gap: 1rem;">
|
||||
<fa-icon [icon]="faSearch"></fa-icon>
|
||||
<fa-icon [icon]="faEllipsisV"></fa-icon>
|
||||
</div>
|
||||
</ui-appbar></code></pre>
|
||||
</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;
|
||||
}
|
||||
|
||||
fa-icon {
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
|
||||
fa-icon:hover {
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
label {
|
||||
font-size: 0.875rem;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
select {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
`]
|
||||
})
|
||||
export class AppbarDemoComponent {
|
||||
// State signals
|
||||
isDarkMode = signal(false);
|
||||
lastAction = signal('');
|
||||
|
||||
// Demo configuration
|
||||
demoConfig = signal({
|
||||
variant: 'standard' as any,
|
||||
elevated: false,
|
||||
title: 'Interactive Demo',
|
||||
slots: {
|
||||
leftIcon: true,
|
||||
leftLogo: false,
|
||||
leftAvatar: false,
|
||||
title: true,
|
||||
rightIcon: true,
|
||||
rightLogo: false,
|
||||
rightAvatar: false,
|
||||
rightMenu: false
|
||||
}
|
||||
});
|
||||
|
||||
// Font Awesome icons
|
||||
faBars = faBars;
|
||||
faSearch = faSearch;
|
||||
faUser = faUser;
|
||||
faHeart = faHeart;
|
||||
faBell = faBell;
|
||||
faCog = faCog;
|
||||
faShoppingCart = faShoppingCart;
|
||||
faHome = faHome;
|
||||
faArrowLeft = faArrowLeft;
|
||||
faPlus = faPlus;
|
||||
faShare = faShare;
|
||||
faEllipsisV = faEllipsisV;
|
||||
faSun = faSun;
|
||||
faMoon = faMoon;
|
||||
|
||||
handleAction(action: string): void {
|
||||
this.lastAction.set(`${action} clicked at ${new Date().toLocaleTimeString()}`);
|
||||
console.log(`Appbar action: ${action}`);
|
||||
}
|
||||
|
||||
toggleTheme(): void {
|
||||
this.isDarkMode.update(current => !current);
|
||||
this.handleAction(`Theme switched to ${this.isDarkMode() ? 'dark' : 'light'} mode`);
|
||||
}
|
||||
|
||||
handleImageError(event: Event): void {
|
||||
const target = event.target as HTMLImageElement;
|
||||
target.style.display = 'none';
|
||||
const fallback = document.createElement('div');
|
||||
fallback.style.width = '32px';
|
||||
fallback.style.height = '32px';
|
||||
fallback.style.borderRadius = '50%';
|
||||
fallback.style.background = 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)';
|
||||
fallback.style.display = 'flex';
|
||||
fallback.style.alignItems = 'center';
|
||||
fallback.style.justifyContent = 'center';
|
||||
fallback.style.color = 'white';
|
||||
fallback.style.fontWeight = '500';
|
||||
fallback.style.fontSize = '12px';
|
||||
fallback.textContent = 'U';
|
||||
target.parentNode?.insertBefore(fallback, target);
|
||||
}
|
||||
|
||||
updateDemoConfig(key: string, event: Event): void {
|
||||
const target = event.target as HTMLInputElement;
|
||||
const value = target.checked;
|
||||
|
||||
this.demoConfig.update(config => ({
|
||||
...config,
|
||||
[key]: value
|
||||
}));
|
||||
}
|
||||
|
||||
updateDemoSlot(slotName: string, event: Event): void {
|
||||
const target = event.target as HTMLInputElement;
|
||||
const checked = target.checked;
|
||||
|
||||
this.demoConfig.update(config => ({
|
||||
...config,
|
||||
slots: {
|
||||
...config.slots,
|
||||
[slotName]: checked
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
updateDemoVariant(event: Event): void {
|
||||
const target = event.target as HTMLSelectElement;
|
||||
const variant = target.value as any;
|
||||
|
||||
this.demoConfig.update(config => ({
|
||||
...config,
|
||||
variant,
|
||||
title: variant.charAt(0).toUpperCase() + variant.slice(1) + ' Demo'
|
||||
}));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user