| 
									
										
										
										
											2025-06-26 15:46:44 +00:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Central z-index management for consistent stacking order | 
					
						
							|  |  |  |  * Higher numbers appear on top of lower numbers | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export const zIndexLayers = { | 
					
						
							|  |  |  |   // Base layer: Regular content
 | 
					
						
							|  |  |  |   base: { | 
					
						
							|  |  |  |     content: 'auto', | 
					
						
							|  |  |  |     inputElements: 1, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Fixed UI elements
 | 
					
						
							|  |  |  |   fixed: { | 
					
						
							|  |  |  |     appBar: 10, | 
					
						
							|  |  |  |     sideMenu: 10, | 
					
						
							|  |  |  |     mobileNav: 250, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Overlay backdrops (semi-transparent backgrounds)
 | 
					
						
							|  |  |  |   backdrop: { | 
					
						
							|  |  |  |     dropdown: 1999,  // Below modals but above fixed elements
 | 
					
						
							|  |  |  |     modal: 2999,     // Below dropdowns on modals
 | 
					
						
							|  |  |  |     contextMenu: 3999, // Below critical overlays
 | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Interactive overlays
 | 
					
						
							|  |  |  |   overlay: { | 
					
						
							|  |  |  |     dropdown: 2000,     // Dropdowns and select menus
 | 
					
						
							|  |  |  |     modal: 3000,        // Modal dialogs
 | 
					
						
							|  |  |  |     contextMenu: 4000,  // Context menus and tooltips
 | 
					
						
							|  |  |  |     toast: 5000,        // Toast notifications (highest priority)
 | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Special cases for nested elements
 | 
					
						
							|  |  |  |   modalDropdown: 3500,    // Dropdowns inside modals
 | 
					
						
							|  |  |  |   wysiwygMenus: 4500,     // Editor formatting menus
 | 
					
						
							|  |  |  | } as const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Helper function to get z-index value
 | 
					
						
							|  |  |  | export function getZIndex(category: keyof typeof zIndexLayers, subcategory?: string): number | string { | 
					
						
							|  |  |  |   const categoryObj = zIndexLayers[category]; | 
					
						
							|  |  |  |   if (typeof categoryObj === 'object' && subcategory) { | 
					
						
							|  |  |  |     return categoryObj[subcategory as keyof typeof categoryObj] || 'auto'; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return typeof categoryObj === 'number' ? categoryObj : 'auto'; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Z-index assignments for components
 | 
					
						
							|  |  |  | export const componentZIndex = { | 
					
						
							|  |  |  |   'dees-modal': zIndexLayers.overlay.modal, | 
					
						
							|  |  |  |   'dees-windowlayer': zIndexLayers.overlay.dropdown, | 
					
						
							|  |  |  |   'dees-contextmenu': zIndexLayers.overlay.contextMenu, | 
					
						
							|  |  |  |   'dees-toast': zIndexLayers.overlay.toast, | 
					
						
							|  |  |  |   'dees-appui-mainmenu': zIndexLayers.fixed.appBar, | 
					
						
							|  |  |  |   'dees-mobilenavigation': zIndexLayers.fixed.mobileNav, | 
					
						
							|  |  |  |   'dees-slash-menu': zIndexLayers.wysiwygMenus, | 
					
						
							|  |  |  |   'dees-formatting-menu': zIndexLayers.wysiwygMenus, | 
					
						
							| 
									
										
										
										
											2025-06-26 18:37:49 +00:00
										 |  |  | } as const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Z-Index Registry for managing stacked elements | 
					
						
							|  |  |  |  * Simple incremental z-index assignment based on creation order | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export class ZIndexRegistry { | 
					
						
							|  |  |  |   private static instance: ZIndexRegistry; | 
					
						
							|  |  |  |   private activeElements = new Set<HTMLElement>(); | 
					
						
							|  |  |  |   private elementZIndexMap = new WeakMap<HTMLElement, number>(); | 
					
						
							|  |  |  |   private currentZIndex = 1000; // Starting z-index
 | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   private constructor() {} | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   public static getInstance(): ZIndexRegistry { | 
					
						
							|  |  |  |     if (!ZIndexRegistry.instance) { | 
					
						
							|  |  |  |       ZIndexRegistry.instance = new ZIndexRegistry(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return ZIndexRegistry.instance; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Get the next available z-index | 
					
						
							|  |  |  |    * @returns The next available z-index | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   public getNextZIndex(): number { | 
					
						
							|  |  |  |     this.currentZIndex += 10; | 
					
						
							|  |  |  |     return this.currentZIndex; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Register an element with the z-index registry | 
					
						
							|  |  |  |    * @param element - The HTML element to register | 
					
						
							|  |  |  |    * @param zIndex - The z-index assigned to this element | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   public register(element: HTMLElement, zIndex: number): void { | 
					
						
							|  |  |  |     this.activeElements.add(element); | 
					
						
							|  |  |  |     this.elementZIndexMap.set(element, zIndex); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Unregister an element from the z-index registry | 
					
						
							|  |  |  |    * @param element - The HTML element to unregister | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   public unregister(element: HTMLElement): void { | 
					
						
							|  |  |  |     this.activeElements.delete(element); | 
					
						
							|  |  |  |     this.elementZIndexMap.delete(element); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     // If no more active elements, reset counter to base
 | 
					
						
							|  |  |  |     if (this.activeElements.size === 0) { | 
					
						
							|  |  |  |       this.currentZIndex = 1000; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Get the z-index for a specific element | 
					
						
							|  |  |  |    * @param element - The HTML element | 
					
						
							|  |  |  |    * @returns The z-index or undefined if not registered | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   public getElementZIndex(element: HTMLElement): number | undefined { | 
					
						
							|  |  |  |     return this.elementZIndexMap.get(element); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Get count of active elements | 
					
						
							|  |  |  |    * @returns Number of active elements | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   public getActiveCount(): number { | 
					
						
							|  |  |  |     return this.activeElements.size; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Get the current highest z-index | 
					
						
							|  |  |  |    * @returns The current z-index value | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   public getCurrentZIndex(): number { | 
					
						
							|  |  |  |     return this.currentZIndex; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Clear all registrations (useful for testing) | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   public clear(): void { | 
					
						
							|  |  |  |     this.activeElements.clear(); | 
					
						
							|  |  |  |     this.elementZIndexMap = new WeakMap(); | 
					
						
							|  |  |  |     this.currentZIndex = 1000; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Get all active elements in z-index order | 
					
						
							|  |  |  |    * @returns Array of elements sorted by z-index | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   public getActiveElementsInOrder(): HTMLElement[] { | 
					
						
							|  |  |  |     return Array.from(this.activeElements).sort((a, b) => { | 
					
						
							|  |  |  |       const aZ = this.elementZIndexMap.get(a) || 0; | 
					
						
							|  |  |  |       const bZ = this.elementZIndexMap.get(b) || 0; | 
					
						
							|  |  |  |       return aZ - bZ; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Export singleton instance for convenience
 | 
					
						
							|  |  |  | export const zIndexRegistry = ZIndexRegistry.getInstance(); |