@panyam/tsappkit 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,866 @@
1
+ /**
2
+ * Simple event system for component communication
3
+ * Provides error isolation and idempotent subscriptions
4
+ */
5
+ /**
6
+ * Simple event handler function type
7
+ */
8
+ type EventHandler = (data?: any) => void;
9
+ /**
10
+ * Interface for components that want to receive events via the EventBus
11
+ */
12
+ interface EventSubscriber {
13
+ /**
14
+ * Handle incoming events from the EventBus
15
+ * @param eventType - The type of event being handled
16
+ * @param data - The event data payload
17
+ * @param subject - The subject/subject entity (what the event is about)
18
+ * @param emitter - The entity that emitted the event
19
+ */
20
+ handleBusEvent(eventType: string, data: any, subject: any, emitter: any): void;
21
+ }
22
+ /**
23
+ * Synchronous event bus for component communication
24
+ * Features:
25
+ * - Type-safe event names and payloads
26
+ * - Error isolation (one handler failure doesn't stop others)
27
+ * - Source exclusion (events not sent back to source)
28
+ * - Debug logging for troubleshooting
29
+ */
30
+ declare class EventBus {
31
+ private subscribers;
32
+ private functionSubscribers;
33
+ private onceHandlers;
34
+ private debugMode;
35
+ constructor(debugMode?: boolean);
36
+ /**
37
+ * Subscribe to an event with a simple handler function
38
+ */
39
+ on(eventType: string, handler: EventHandler): void;
40
+ /**
41
+ * Unsubscribe a handler function from an event
42
+ */
43
+ off(eventType: string, handler: EventHandler): void;
44
+ /**
45
+ * Subscribe to an event for one-time execution
46
+ */
47
+ once(eventType: string, handler: EventHandler): void;
48
+ /**
49
+ * Add a subscription using the EventSubscriber pattern
50
+ * Provides automatic idempotency - same subscriber object won't be added twice
51
+ */
52
+ addSubscription(eventType: string, subject: any, subscriber: EventSubscriber): void;
53
+ /**
54
+ * Remove a subscription using the EventSubscriber pattern
55
+ */
56
+ removeSubscription(eventType: string, subject: any, subscriber: EventSubscriber): void;
57
+ /**
58
+ * Emit an event to all subscribers
59
+ * @param eventType - The event type to emit
60
+ * @param data - The event data payload
61
+ * @param subject - The subject/subject entity that this event relates to (optional for simple API)
62
+ * @param emitter - The entity that emitted the event (optional for simple API)
63
+ */
64
+ emit<T = any>(eventType: string, data?: T, subject?: any, emitter?: any): void;
65
+ /**
66
+ * Get all event types that have subscribers
67
+ */
68
+ getEventTypes(): string[];
69
+ /**
70
+ * Get subscriber count for an event type
71
+ */
72
+ getSubscriberCount(eventType: string): number;
73
+ /**
74
+ * Clear all subscriptions (useful for cleanup)
75
+ */
76
+ clear(): void;
77
+ /**
78
+ * Enable or disable debug logging
79
+ */
80
+ setDebugMode(enabled: boolean): void;
81
+ }
82
+ declare const ComponentEventTypes: {
83
+ readonly COMPONENT_INITIALIZED: "component-initialized";
84
+ readonly COMPONENT_HYDRATED: "component-hydrated";
85
+ readonly COMPONENT_ERROR: "component-error";
86
+ };
87
+ declare const LifecycleEventTypes: {
88
+ readonly LOCAL_INIT_STARTED: "lifecycle-local-init-started";
89
+ readonly LOCAL_INIT_FINISHED: "lifecycle-local-init-finished";
90
+ readonly DEPENDENCIES_INJECTED: "lifecycle-dependencies-injected";
91
+ readonly ACTIVATION_STARTED: "lifecycle-activation-started";
92
+ readonly ACTIVATION_FINISHED: "lifecycle-activation-finished";
93
+ readonly DEACTIVATION_STARTED: "lifecycle-deactivation-started";
94
+ readonly DEACTIVATION_FINISHED: "lifecycle-deactivation-finished";
95
+ };
96
+ type LifecycleEventType = typeof LifecycleEventTypes[keyof typeof LifecycleEventTypes];
97
+ type ComponentEventType = typeof ComponentEventTypes[keyof typeof ComponentEventTypes];
98
+
99
+ /**
100
+ * LCMComponent Interface - Defines multi-phase component initialization
101
+ *
102
+ * This interface implements a breadth-first lifecycle pattern that eliminates
103
+ * initialization order dependencies and race conditions through synchronization barriers.
104
+ *
105
+ * Lifecycle Phases:
106
+ * 1. Construction - Components are created but not initialized
107
+ * 2. bindToDOM() - Basic DOM setup, discover child components
108
+ * 3. injectDependencies() - Receive references to other components
109
+ * 4. activate() - Final setup when all dependencies are ready
110
+ *
111
+ * Key Benefits:
112
+ * - Order Independence: Components can be created in any sequence
113
+ * - Async Safety: Each phase waits for all components before proceeding
114
+ * - Clear Dependencies: Explicit injection points prevent race conditions
115
+ * - Error Isolation: Component failures don't cascade to others
116
+ */
117
+ /**
118
+ * LCM Component - Short for LifeCycle Managed Component
119
+ * enable components to be declared first and their loading be managed by a
120
+ * LifecycleController so that we have layered creation, dependency injection and setup
121
+ * in a breadth first way.
122
+ *
123
+ * A key constraint on LCMComponents are that they should not perform any initialization
124
+ * in the constructor. This is because a LifecycleController should be used to load/setup
125
+ * these components and they will follow a layered approach. Performing these actions in
126
+ * the constructor could violate the idempotency guarantees.
127
+ */
128
+ interface LCMComponent {
129
+ /**
130
+ * Phase 1: The "local" initialization of the component.
131
+ *
132
+ * In this phase the component initializes itself and returns any children it might
133
+ * want initialized as part of the lifecycled loading.
134
+ *
135
+ * This phase should:
136
+ * - Set up basic DOM elements and event listeners
137
+ * - Create child components (but don't initialize them) and return them
138
+ * - Return array of child components for lifecycle controller discovery
139
+ *
140
+ * This phase must be synchronous and should not:
141
+ * - Access other components or external dependencies
142
+ * - Perform async operations
143
+ * - Emit events or notifications
144
+ *
145
+ * @returns Array of child components to be managed by lifecycle controller
146
+ */
147
+ performLocalInit(): Promise<LCMComponent[]> | LCMComponent[];
148
+ /**
149
+ * Phase 2: Inject dependencies from parent/siblings
150
+ *
151
+ * This phase should:
152
+ * - Receive and store references to required dependencies
153
+ * - Validate that required dependencies are provided
154
+ * - Set up internal state based on dependencies
155
+ *
156
+ * This phase can be async and may:
157
+ * - Load external data or resources
158
+ * - Perform validation or setup operations
159
+ * - Initialize internal components that depend on injected references
160
+ *
161
+ * @param deps Record of dependency name to dependency instance
162
+ * @returns Promise<void> or void - can be async
163
+ */
164
+ setupDependencies(): Promise<void> | void;
165
+ /**
166
+ * Phase 3: Activate component when all dependencies are ready
167
+ *
168
+ * This phase should:
169
+ * - Complete final initialization
170
+ * - Enable component functionality
171
+ * - Start listening for external events
172
+ * - Begin normal operation
173
+ *
174
+ * This phase can be async and may:
175
+ * - Connect to external services
176
+ * - Load initial data
177
+ * - Emit ready notifications
178
+ *
179
+ * @returns Promise<void> or void - can be async
180
+ */
181
+ activate(): Promise<void> | void;
182
+ /**
183
+ * Cleanup phase: Deactivate component and clean up resources
184
+ *
185
+ * This should:
186
+ * - Stop all ongoing operations
187
+ * - Remove event listeners
188
+ * - Clean up external connections
189
+ * - Dispose of child components
190
+ *
191
+ * @returns Promise<void> or void - can be async
192
+ */
193
+ deactivate(): Promise<void> | void;
194
+ }
195
+ /**
196
+ * Configuration for component lifecycle behavior
197
+ */
198
+ interface LCMComponentConfig {
199
+ /**
200
+ * Maximum time to wait for a lifecycle phase to complete (ms)
201
+ * Default: 10000 (10 seconds)
202
+ */
203
+ phaseTimeoutMs?: number;
204
+ /**
205
+ * Whether to continue if individual components fail during a phase
206
+ * Default: false (fail fast)
207
+ */
208
+ continueOnError?: boolean;
209
+ /**
210
+ * Whether to validate dependencies against declared requirements
211
+ * Default: true
212
+ */
213
+ validateDependencies?: boolean;
214
+ /**
215
+ * Enable debug logging for lifecycle phases
216
+ * Default: false
217
+ */
218
+ enableDebugLogging?: boolean;
219
+ }
220
+ /**
221
+ * Event emitted during component lifecycle transitions
222
+ */
223
+ interface LCMComponentEvent {
224
+ type: 'phase-start' | 'phase-complete' | 'phase-error' | 'component-ready';
225
+ componentName: string;
226
+ timestamp: number;
227
+ error?: Error;
228
+ metadata?: Record<string, any>;
229
+ }
230
+
231
+ /**
232
+ * Base interface for all UI components
233
+ * Enforces separation of concerns and standard lifecycle
234
+ */
235
+ interface Component {
236
+ /**
237
+ * Unique identifier for this component instance
238
+ */
239
+ readonly componentId: string;
240
+ /**
241
+ * Root DOM element that this component owns and manages
242
+ */
243
+ readonly rootElement: HTMLElement;
244
+ /**
245
+ * Handle dynamic content updates (e.g., from HTMX or server responses)
246
+ * @param newHTML - New HTML content to replace current content
247
+ */
248
+ contentUpdated(newHTML: string): void;
249
+ }
250
+ /**
251
+ * Abstract base class implementing common component functionality
252
+ * Provides standard lifecycle management and event bus integration
253
+ *
254
+ * All components auto-initialize in constructor AND implement LCMComponent
255
+ * for coordination with other components when needed.
256
+ */
257
+ declare abstract class BaseComponent implements Component, LCMComponent, EventSubscriber {
258
+ readonly componentId: string;
259
+ readonly rootElement: HTMLElement;
260
+ readonly debugMode: boolean;
261
+ protected _eventBus: EventBus;
262
+ constructor(componentId: string, rootElement: HTMLElement, eventBus?: EventBus | null, debugMode?: boolean);
263
+ get eventBus(): EventBus;
264
+ contentUpdated(newHTML: string): void;
265
+ /**
266
+ * Subscribe to an event using the new EventSubscriber pattern
267
+ */
268
+ protected addSubscription(eventType: string, target?: any): void;
269
+ /**
270
+ * Unsubscribe from an event using the new EventSubscriber pattern
271
+ */
272
+ protected removeSubscription(eventType: string, target?: any): void;
273
+ /**
274
+ * Emit an event from this component
275
+ */
276
+ protected emit<T = any>(eventType: string, data: T, target: any, emitter?: any): void;
277
+ /**
278
+ * Default implementation of EventSubscriber interface
279
+ * Components can override this to handle events
280
+ */
281
+ handleBusEvent(eventType: string, data: any, target: any, emitter: any): void;
282
+ /**
283
+ * Find elements within this component's root element only
284
+ * Enforces separation of concerns - no cross-component DOM access
285
+ */
286
+ protected findElement<T extends HTMLElement = HTMLElement>(selector: string): T | null;
287
+ /**
288
+ * Find multiple elements within this component's root element only
289
+ */
290
+ protected findElements<T extends HTMLElement = HTMLElement>(selector: string): T[];
291
+ /**
292
+ * Log messages with component identification
293
+ */
294
+ protected log(message: string, data?: any): void;
295
+ /**
296
+ * Default lifecycle method: discover and return child components
297
+ * Override this if your component creates child components that need lifecycle management
298
+ */
299
+ performLocalInit(): Promise<LCMComponent[]> | LCMComponent[];
300
+ /**
301
+ * Default lifecycle method: inject dependencies
302
+ * Override this if your component needs dependencies from other components
303
+ */
304
+ setupDependencies(): void | Promise<void>;
305
+ /**
306
+ * Default lifecycle method: activate component for coordination
307
+ * Override this if your component needs to coordinate with other components after initialization
308
+ */
309
+ activate(): void | Promise<void>;
310
+ /**
311
+ * Default lifecycle method: deactivate component
312
+ * Override this if your component needs cleanup during lifecycle management
313
+ */
314
+ deactivate(): void | Promise<void>;
315
+ set innerHTML(innerHTML: string);
316
+ shouldUpdateHtml(html: string): [string, boolean];
317
+ htmlUpdated(html: string): void;
318
+ }
319
+
320
+ /**
321
+ * LifecycleController - Orchestrates breadth-first component initialization
322
+ *
323
+ * This controller implements a breadth-first traversal of the component tree
324
+ * followed by phase-wise initialization with synchronization barriers.
325
+ *
326
+ * Process:
327
+ * 1. Discovery Phase: Traverse component tree to find all components
328
+ * 2. DOM Binding Phase: All components bind to DOM simultaneously
329
+ * 3. Dependency Injection Phase: All components receive dependencies
330
+ * 4. Activation Phase: All components complete initialization
331
+ *
332
+ * Each phase acts as a synchronization barrier - no component can proceed
333
+ * to the next phase until ALL components have completed the current phase.
334
+ */
335
+ declare class LifecycleController {
336
+ protected eventBus: EventBus;
337
+ private allComponents;
338
+ private componentsByLevel;
339
+ private config;
340
+ static DefaultConfig: LCMComponentConfig;
341
+ constructor(eventBus: EventBus, config?: LCMComponentConfig);
342
+ /**
343
+ * Initialize component tree starting from root component
344
+ *
345
+ * @param rootComponent The root component to start initialization from
346
+ * @param rootName Optional name for the root component (for debugging)
347
+ * @returns Promise that resolves when all components are fully initialized
348
+ */
349
+ initializeFromRoot(rootComponent: LCMComponent): Promise<void>;
350
+ /**
351
+ * Phase 0: Discover all components via breadth-first traversal
352
+ */
353
+ private performLocalInit;
354
+ /**
355
+ * Phase 1: Dependency injection.
356
+ * Here all our components are already discovered so we can call directly
357
+ */
358
+ protected injectDependencies(): void;
359
+ /**
360
+ * Phase 2: Activate all components
361
+ *
362
+ * Here all our components are already discovered and their dependencies setup
363
+ * so we can call directly
364
+ */
365
+ protected activate(): Promise<void>;
366
+ /**
367
+ * Deactivate all components in reverse order. This is usually called when a page quits or a component is
368
+ * deactivated
369
+ */
370
+ deactivateAll(): Promise<void>;
371
+ /**
372
+ * Emit lifecycle event to registered callbacks
373
+ */
374
+ private emitEvent;
375
+ /**
376
+ * Log message if debug logging is enabled
377
+ */
378
+ private log;
379
+ /**
380
+ * Log error message
381
+ */
382
+ private logError;
383
+ }
384
+
385
+ interface ComponentLifecycleEvent {
386
+ success: boolean;
387
+ error: Error | null;
388
+ }
389
+
390
+ /**
391
+ * Theme management for applications
392
+ */
393
+ declare class ThemeManager {
394
+ static LIGHT: string;
395
+ static DARK: string;
396
+ static SYSTEM: string;
397
+ static readonly LIGHT_ICON_SVG = "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-full h-6\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z\" /></svg>";
398
+ static readonly DARK_ICON_SVG = "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-full h-6\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z\" /></svg>";
399
+ static readonly SYSTEM_ICON_SVG = "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-full h-6\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 17.25v1.007a3 3 0 01-.879 2.122L7.5 21h9l-.621-.621A3 3 0 0115 18.257V17.25m6-12V15a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 15V5.25m18 0A2.25 2.25 0 0018.75 3H5.25A2.25 2.25 0 003 5.25m18 0V12a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 12V5.25\" /></svg>";
400
+ /**
401
+ * Initialize theme based on saved preference or system default
402
+ */
403
+ static initialize(): void;
404
+ /**
405
+ * Set theme and save preference
406
+ */
407
+ static setTheme(theme: string): void;
408
+ /**
409
+ * Get current theme setting (light, dark, or system)
410
+ */
411
+ static getCurrentThemeSetting(): string;
412
+ /**
413
+ * Gets the *next* theme in the cycle: Light -> Dark -> System -> Light ...
414
+ */
415
+ static getNextTheme(currentSetting: string): string;
416
+ /**
417
+ * Gets the appropriate SVG icon string for a given theme setting.
418
+ */
419
+ static getIconSVG(themeSetting: string): string;
420
+ /**
421
+ * Gets a user-friendly label for the theme setting.
422
+ */
423
+ static getThemeLabel(themeSetting: string): string;
424
+ /**
425
+ * Initialize the ThemeManager (no instance needed for static methods)
426
+ */
427
+ static init(): void;
428
+ }
429
+
430
+ /**
431
+ * Modal manager for the application
432
+ * Handles showing and hiding modals with different content
433
+ */
434
+ declare class Modal {
435
+ private static instance;
436
+ private modalContainer;
437
+ private modalBackdrop;
438
+ private modalPanel;
439
+ private modalContent;
440
+ private closeButton;
441
+ private templateLoader;
442
+ private currentTemplateId;
443
+ private currentData;
444
+ private onSubmitCallback;
445
+ private onApplyCallback;
446
+ /**
447
+ * Private constructor for singleton pattern
448
+ */
449
+ private constructor();
450
+ /**
451
+ * Get the Modal instance (singleton)
452
+ */
453
+ static getInstance(): Modal;
454
+ /**
455
+ * Bind event listeners for modal interactions
456
+ */
457
+ private bindEvents;
458
+ /**
459
+ * Check if the modal is currently visible
460
+ */
461
+ isVisible(): boolean;
462
+ /**
463
+ * Show a modal with content from the specified template ID.
464
+ * Uses TemplateLoader to get the content element.
465
+ * @param templateId ID used in `data-template-id` attribute in TemplateRegistry.html
466
+ * @param data Optional data to pass to the modal. Can include callbacks like `onSubmit`.
467
+ * @returns The root HTMLElement of the loaded content, or null if failed.
468
+ */
469
+ show(templateId: string, data?: any): HTMLElement | null;
470
+ /**
471
+ * Hide the modal
472
+ */
473
+ hide(): Promise<void>;
474
+ /**
475
+ * Get the current modal content element
476
+ */
477
+ getContentElement(): HTMLElement | null;
478
+ /**
479
+ * Get the current template ID
480
+ */
481
+ getCurrentTemplate(): string | null;
482
+ /**
483
+ * Get the current modal data
484
+ */
485
+ getCurrentData(): any;
486
+ /**
487
+ * Update modal data (excluding callbacks for now)
488
+ */
489
+ updateData(newData: any): void;
490
+ /**
491
+ * Initialize the modal component
492
+ */
493
+ static init(): Modal;
494
+ }
495
+
496
+ /**
497
+ * Toast types for styling
498
+ */
499
+ type ToastType = 'success' | 'error' | 'info' | 'warning';
500
+ /**
501
+ * Manages toast notifications
502
+ */
503
+ declare class ToastManager {
504
+ private static instance;
505
+ private container;
506
+ private template;
507
+ private toasts;
508
+ private counter;
509
+ /**
510
+ * Private constructor for singleton pattern
511
+ */
512
+ private constructor();
513
+ /**
514
+ * Get the ToastManager instance (singleton)
515
+ */
516
+ static getInstance(): ToastManager;
517
+ /**
518
+ * Show a toast notification
519
+ * @param title Toast title
520
+ * @param message Toast message
521
+ * @param type Toast type for styling
522
+ * @param duration Duration in ms (default: 4000)
523
+ */
524
+ showToast(title: string, message: string, type?: ToastType, duration?: number): string;
525
+ /**
526
+ * Hide a toast notification
527
+ * @param id Toast ID
528
+ */
529
+ hideToast(id: string): void;
530
+ /**
531
+ * Hide all toast notifications
532
+ */
533
+ hideAllToasts(): void;
534
+ /**
535
+ * Initialize the component
536
+ */
537
+ static init(): ToastManager;
538
+ }
539
+
540
+ /**
541
+ * Base class for all pages that provides common UI components and functionality
542
+ * Implements proper LCMComponent lifecycle management for pages
543
+ */
544
+ declare abstract class BasePage extends BaseComponent {
545
+ readonly componentId: string;
546
+ readonly debugMode: boolean;
547
+ protected themeManager: typeof ThemeManager;
548
+ protected modal: Modal;
549
+ protected toastManager: ToastManager;
550
+ protected themeToggleButton: HTMLButtonElement;
551
+ protected themeToggleIcon: HTMLElement;
552
+ constructor(componentId: string, eventBus?: EventBus | null, debugMode?: boolean);
553
+ performLocalInit(): Promise<LCMComponent[]> | LCMComponent[];
554
+ activate(): void;
555
+ /**
556
+ * Initialize common UI components that all pages need
557
+ */
558
+ protected initializeBaseComponents(): void;
559
+ /**
560
+ * Bind common event handlers that all pages need
561
+ */
562
+ protected bindBaseEvents(): void;
563
+ /**
564
+ * Handle theme toggle button clicks
565
+ */
566
+ protected handleThemeToggleClick(): void;
567
+ /**
568
+ * Update the theme toggle button state and appearance
569
+ */
570
+ protected updateThemeButtonState(currentTheme?: string): void;
571
+ /**
572
+ * Show a toast notification
573
+ */
574
+ protected showToast(title: string, message: string, type?: 'success' | 'error' | 'info' | 'warning', duration?: number): void;
575
+ /**
576
+ * Show a modal dialog
577
+ */
578
+ protected showModal(templateId: string, data?: any): void;
579
+ /**
580
+ * Hide the modal dialog
581
+ */
582
+ protected hideModal(): void;
583
+ /**
584
+ * Get the current theme setting
585
+ */
586
+ protected getCurrentTheme(): string;
587
+ /**
588
+ * Check if the current theme is dark mode
589
+ */
590
+ protected isDarkMode(): boolean;
591
+ /**
592
+ * Initialize responsive header actions drawer
593
+ * On desktop: drawer is always visible, positioned inline with header
594
+ * On mobile: drawer slides down from top when menu button is clicked
595
+ */
596
+ protected initializeHeaderActionsDropdown(): void;
597
+ /**
598
+ * Abstract method that subclasses must implement to initialize their specific components
599
+ * Should return any child components that need lifecycle management
600
+ */
601
+ protected initializeSpecificComponents(): LCMComponent[];
602
+ /**
603
+ * Abstract method that subclasses must implement to bind their specific events
604
+ */
605
+ protected bindSpecificEvents(): void;
606
+ /**
607
+ * Component-specific cleanup logic (required by BaseComponent)
608
+ */
609
+ protected destroyComponent(): void;
610
+ /**
611
+ * Ensure an element exists, create if missing
612
+ * This is acceptable for page-level orchestration to find component root elements
613
+ */
614
+ protected ensureElement(selector: string, fallbackId: string): HTMLElement;
615
+ protected dismissSplashScreen(): void;
616
+ static loadAfterPageLoaded<T>(pageName: string, PageClass: any, PageClassName: string): void;
617
+ }
618
+
619
+ declare class TemplateLoader {
620
+ registryName: string;
621
+ constructor(registryName?: string);
622
+ /**
623
+ * Finds the specified template wrapper element in the registry.
624
+ * @param templateId The data-template-id of the wrapper element.
625
+ * @returns The wrapper HTMLElement or null if not found.
626
+ */
627
+ private _findTemplateWrapper;
628
+ /**
629
+ * Loads and returns the inner HTML of a template definition.
630
+ * @param templateId The data-template-id of the wrapper element.
631
+ * @returns The innerHTML content as string if it exists otherwise null.
632
+ */
633
+ loadHtml(templateId: string): string | null;
634
+ /**
635
+ * Loads and clones the child elements of a template definition.
636
+ * @param templateId The data-template-id of the wrapper element.
637
+ * @returns An array of cloned HTMLElement children, or an empty array if not found or has no children.
638
+ */
639
+ load(templateId: string): HTMLElement[];
640
+ /**
641
+ * Loads a template's content, clears the target element, and appends the cloned content into it.
642
+ * @param templateId The data-template-id of the wrapper element to load.
643
+ * @param targetElement The HTMLElement where the cloned content should be placed.
644
+ * @returns True if the operation was successful (template found and content appended, even if content was empty), false otherwise.
645
+ */
646
+ loadInto(templateId: string, targetElement: HTMLElement | null): boolean;
647
+ }
648
+
649
+ /**
650
+ * Utility for managing the splash screen that loads before JavaScript
651
+ */
652
+ declare class SplashScreen {
653
+ private static readonly SPLASH_ID;
654
+ private static dismissed;
655
+ /**
656
+ * Dismiss the splash screen with a fade-out animation
657
+ * Safe to call multiple times - only dismisses once
658
+ */
659
+ static dismiss(): void;
660
+ /**
661
+ * Update the splash screen message (if it hasn't been dismissed yet)
662
+ */
663
+ static updateMessage(title?: string, message?: string): void;
664
+ /**
665
+ * Update the splash screen progress bar
666
+ * @param percent - Progress percentage (0-100)
667
+ */
668
+ static updateProgress(percent: number): void;
669
+ /**
670
+ * Update both message and progress at once
671
+ */
672
+ static update(options: {
673
+ title?: string;
674
+ message?: string;
675
+ progress?: number;
676
+ }): void;
677
+ /**
678
+ * Check if splash screen is still visible
679
+ */
680
+ static isVisible(): boolean;
681
+ }
682
+
683
+ /**
684
+ * MobileBottomDrawer - Reusable bottom drawer component for mobile layouts
685
+ *
686
+ * Features:
687
+ * - Slides up from bottom covering 60-70% of viewport
688
+ * - Backdrop overlay that dims the content behind
689
+ * - Auto-closes when backdrop is tapped
690
+ * - Swipe down to close gesture
691
+ * - Smooth slide-up/down animations
692
+ * - Holds any panel content
693
+ */
694
+ declare class MobileBottomDrawer extends BaseComponent implements LCMComponent {
695
+ private backdropElement;
696
+ private drawerElement;
697
+ private contentElement;
698
+ private closeButton;
699
+ private isOpen;
700
+ private onCloseCallback?;
701
+ private touchStartY;
702
+ private touchCurrentY;
703
+ private isDragging;
704
+ /**
705
+ * Create a MobileBottomDrawer
706
+ * @param rootElement - The root container element for the drawer
707
+ * @param eventBus - Event bus for component communication
708
+ * @param debugMode - Enable debug logging
709
+ */
710
+ constructor(rootElement: HTMLElement, eventBus: EventBus, debugMode?: boolean);
711
+ /**
712
+ * Phase 1: Initialize DOM and discover child components
713
+ */
714
+ performLocalInit(): Promise<LCMComponent[]>;
715
+ /**
716
+ * Bind event listeners for drawer interactions
717
+ */
718
+ private bindEvents;
719
+ /**
720
+ * Handle touch start for swipe gesture
721
+ */
722
+ private handleTouchStart;
723
+ /**
724
+ * Handle touch move for swipe gesture
725
+ */
726
+ private handleTouchMove;
727
+ /**
728
+ * Handle touch end for swipe gesture
729
+ */
730
+ private handleTouchEnd;
731
+ /**
732
+ * Open the drawer with slide-up animation
733
+ */
734
+ open(): void;
735
+ /**
736
+ * Close the drawer with slide-down animation
737
+ */
738
+ close(): void;
739
+ /**
740
+ * Toggle drawer open/closed
741
+ */
742
+ toggle(): void;
743
+ /**
744
+ * Check if drawer is currently open
745
+ */
746
+ getIsOpen(): boolean;
747
+ /**
748
+ * Set the content element for the drawer
749
+ * @param element - The element to insert into the drawer content area
750
+ */
751
+ setContent(element: HTMLElement): void;
752
+ /**
753
+ * Set a callback to be called when drawer closes
754
+ * @param callback - Function to call on close
755
+ */
756
+ setOnClose(callback: () => void): void;
757
+ /**
758
+ * Get the content container element
759
+ */
760
+ getContentContainer(): HTMLElement;
761
+ }
762
+
763
+ /**
764
+ * Common DOM utility functions for consistent behavior across components
765
+ */
766
+ /**
767
+ * Checks if the user is currently typing in an input field, textarea, or other editable element.
768
+ * This is used to prevent keyboard shortcuts from interfering with user input.
769
+ *
770
+ * @param element - The target element from a keyboard event
771
+ * @returns true if the user is in an input context, false otherwise
772
+ */
773
+ declare function isInInputContext(element: HTMLElement | null): boolean;
774
+ /**
775
+ * Checks if modifier keys are pressed (Ctrl, Alt, Cmd, Shift).
776
+ * This is commonly used to filter keyboard shortcuts.
777
+ *
778
+ * @param event - The keyboard event
779
+ * @returns true if any modifier keys are pressed, false otherwise
780
+ */
781
+ declare function hasModifierKeys(event: KeyboardEvent): boolean;
782
+ /**
783
+ * Combined check for whether keyboard shortcuts should be ignored.
784
+ * This checks both modifier keys and input context.
785
+ *
786
+ * @param event - The keyboard event
787
+ * @returns true if shortcuts should be ignored, false if they can be processed
788
+ */
789
+ declare function shouldIgnoreShortcut(event: KeyboardEvent): boolean;
790
+
791
+ /**
792
+ * Generic keyboard shortcut manager for handling multi-key commands
793
+ * across all application pages
794
+ *
795
+ * Current Behavior (default):
796
+ * - User types 'c3' → visual indicator → Enter/timeout → execute
797
+ * - Requires explicit confirmation for execution
798
+ *
799
+ * Future Immediate Mode (when enabled):
800
+ * - User types 'c3' → immediate preview → Escape to cancel
801
+ * - Provides instant feedback with option to cancel
802
+ */
803
+ interface ShortcutConfig {
804
+ key: string;
805
+ handler: (args?: string) => void;
806
+ description: string;
807
+ category?: string;
808
+ requiresArgs?: boolean;
809
+ argType?: 'number' | 'string';
810
+ contextFilter?: (event: KeyboardEvent) => boolean;
811
+ previewHandler?: (args?: string) => void;
812
+ cancelHandler?: () => void;
813
+ executeImmediately?: boolean;
814
+ }
815
+ interface ShortcutManagerConfig {
816
+ shortcuts: ShortcutConfig[];
817
+ helpContainer?: string;
818
+ timeout?: number;
819
+ immediateExecution?: boolean;
820
+ previewDelay?: number;
821
+ onStateChange?: (state: KeyboardState, command?: string) => void;
822
+ }
823
+ declare enum KeyboardState {
824
+ NORMAL = "normal",
825
+ AWAITING_ARGS = "awaiting_args"
826
+ }
827
+ declare class KeyboardShortcutManager {
828
+ private shortcuts;
829
+ private state;
830
+ private currentCommand;
831
+ private currentArgs;
832
+ private helpContainer;
833
+ private timeout;
834
+ private timeoutId;
835
+ private helpOverlay;
836
+ private immediateExecution;
837
+ private previewDelay;
838
+ private previewTimeoutId;
839
+ private isPreviewActive;
840
+ private onStateChange;
841
+ constructor(config: ShortcutManagerConfig);
842
+ private initialize;
843
+ private handleKeydown;
844
+ private handleNormalState;
845
+ private handleAwaitingArgsState;
846
+ private executeCurrentCommand;
847
+ private executeShortcut;
848
+ private schedulePreviewExecution;
849
+ private cancelPreviewExecution;
850
+ private executePreview;
851
+ private cancelCurrentPreview;
852
+ private resetState;
853
+ private startTimeout;
854
+ private resetTimeout;
855
+ private clearTimeout;
856
+ private updateStateIndicator;
857
+ private showHelp;
858
+ private hideHelp;
859
+ private generateHelpContent;
860
+ destroy(): void;
861
+ getState(): KeyboardState;
862
+ getCurrentCommand(): string;
863
+ getCurrentArgs(): string;
864
+ }
865
+
866
+ export { BaseComponent, BasePage, type Component, type ComponentEventType, ComponentEventTypes, type ComponentLifecycleEvent, EventBus, type EventHandler, type EventSubscriber, KeyboardShortcutManager, KeyboardState, type LCMComponent, type LCMComponentConfig, type LCMComponentEvent, LifecycleController, type LifecycleEventType, LifecycleEventTypes, MobileBottomDrawer, Modal, type ShortcutConfig, type ShortcutManagerConfig, SplashScreen, TemplateLoader, ThemeManager, ToastManager, hasModifierKeys, isInInputContext, shouldIgnoreShortcut };