/** * 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, } 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(); private elementZIndexMap = new WeakMap(); 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();