|
1 | | -import { Component, signal } from '@angular/core'; |
| 1 | +import { Component, signal, HostListener } from '@angular/core'; |
2 | 2 | import { CommonModule } from '@angular/common'; |
3 | 3 | import { ConfigStoreService } from '../services/config-store.service'; |
4 | 4 | import { CategoryNavigationComponent } from '../components/category-navigation/category-navigation.component'; |
@@ -26,29 +26,30 @@ import { AboutModalComponent } from '../components/about-modal/about-modal.compo |
26 | 26 | } |
27 | 27 |
|
28 | 28 | <div class="flex flex-1 overflow-hidden relative"> |
29 | | - <!-- Mobile overlay backdrop --> |
| 29 | + <!-- Mobile overlay backdrop with fade animation --> |
30 | 30 | @if (configStore.sidebarOpen()) { |
31 | 31 | <div |
32 | | - class="fixed inset-0 bg-black/50 z-30 lg:hidden" |
| 32 | + class="fixed inset-0 bg-black/50 z-30 lg:hidden animate-fade-in" |
33 | 33 | (click)="configStore.setSidebarOpen(false)" |
34 | 34 | ></div> |
35 | 35 | } |
36 | 36 |
|
37 | | - <!-- Sidebar navigation --> |
| 37 | + <!-- Sidebar navigation with enhanced animation --> |
38 | 38 | <app-category-navigation |
39 | | - class="absolute lg:relative z-40 h-full w-72 flex-shrink-0 transform transition-transform duration-300 ease-out lg:translate-x-0" |
| 39 | + class="absolute lg:relative z-40 h-full w-72 flex-shrink-0 transform transition-all duration-300 ease-out lg:translate-x-0 shadow-2xl lg:shadow-none" |
40 | 40 | [class.-translate-x-full]="!configStore.sidebarOpen()" |
| 41 | + [class.opacity-0]="!configStore.sidebarOpen()" |
41 | 42 | /> |
42 | 43 |
|
43 | 44 | <!-- Main content area --> |
44 | 45 | <main class="flex-1 overflow-hidden flex flex-col lg:flex-row min-w-0"> |
45 | 46 | <!-- Config editor --> |
46 | 47 | <app-config-editor class="flex-1 overflow-y-auto min-w-0" /> |
47 | 48 |
|
48 | | - <!-- Preview panel - full screen on mobile when visible, side panel on desktop --> |
| 49 | + <!-- Preview panel with slide-in animation on mobile --> |
49 | 50 | @if (configStore.previewVisible()) { |
50 | 51 | <app-live-preview |
51 | | - class="fixed inset-0 z-50 lg:static lg:z-auto lg:w-2/5 lg:flex-shrink-0 lg:border-l lg:border-kitty-border bg-kitty-darker" |
| 52 | + class="fixed inset-0 z-50 lg:static lg:z-auto lg:w-2/5 lg:flex-shrink-0 lg:border-l lg:border-kitty-border bg-kitty-darker animate-slide-in-right lg:animate-none" |
52 | 53 | /> |
53 | 54 | } |
54 | 55 | </main> |
@@ -79,13 +80,40 @@ import { AboutModalComponent } from '../components/about-modal/about-modal.compo |
79 | 80 | :host { |
80 | 81 | display: block; |
81 | 82 | } |
| 83 | + @keyframes fade-in { |
| 84 | + from { opacity: 0; } |
| 85 | + to { opacity: 1; } |
| 86 | + } |
| 87 | + @keyframes slide-in-right { |
| 88 | + from { transform: translateX(100%); opacity: 0; } |
| 89 | + to { transform: translateX(0); opacity: 1; } |
| 90 | + } |
| 91 | + .animate-fade-in { |
| 92 | + animation: fade-in 0.2s ease-out; |
| 93 | + } |
| 94 | + .animate-slide-in-right { |
| 95 | + animation: slide-in-right 0.25s ease-out; |
| 96 | + } |
82 | 97 | `] |
83 | 98 | }) |
84 | 99 | export class AppComponent { |
85 | 100 | readonly showAbout = signal(false); |
86 | 101 |
|
87 | 102 | constructor(public configStore: ConfigStoreService) {} |
88 | 103 |
|
| 104 | + @HostListener('window:keydown.escape') |
| 105 | + onEscape(): void { |
| 106 | + if (this.configStore.sidebarOpen()) { |
| 107 | + this.configStore.setSidebarOpen(false); |
| 108 | + } |
| 109 | + if (this.configStore.previewVisible()) { |
| 110 | + this.configStore.setPreviewVisible(false); |
| 111 | + } |
| 112 | + if (this.showAbout()) { |
| 113 | + this.showAbout.set(false); |
| 114 | + } |
| 115 | + } |
| 116 | + |
89 | 117 | openKofi(): void { |
90 | 118 | globalThis.open('https://ko-fi.com/xcutiboo', '_blank', 'noopener,noreferrer'); |
91 | 119 | } |
|
0 commit comments