ngx-custom-modal
Version:
A custom Modal / Dialog (with inner component support) for Angular 17-20 projects with full version compatibility
1 lines • 47.3 kB
Source Map (JSON)
{"version":3,"file":"ngx-custom-modal.mjs","sources":["../../../projects/ngx-custom-modal/src/lib/ngx-modal-stack.service.ts","../../../projects/ngx-custom-modal/src/lib/compatibility/lifecycle-compatibility.service.ts","../../../projects/ngx-custom-modal/src/lib/ngx-custom-modal.component.ts","../../../projects/ngx-custom-modal/src/lib/ngx-custom-modal.component.html","../../../projects/ngx-custom-modal/src/public-api.ts","../../../projects/ngx-custom-modal/src/ngx-custom-modal.ts"],"sourcesContent":["import { Injectable, signal } from '@angular/core';\nimport { NgxCustomModalComponent } from './ngx-custom-modal.component';\n\n/**\n * Service for managing multiple modal instances and their stacking order.\n *\n * Handles:\n * - Z-index calculation for proper stacking\n * - Modal registration/unregistration\n * - Top-most modal identification\n * - Body class management\n *\n * @injectable\n * @public\n */\n@Injectable({ providedIn: 'root' })\nexport class NgxModalStackService {\n private modals = signal<NgxCustomModalComponent[]>([]);\n private baseZIndex = 1050;\n\n /**\n * Registers a modal instance with the stack service.\n * @param modal - The modal component to register\n * @public\n */\n register(modal: NgxCustomModalComponent): void {\n this.modals.update(modals => [...modals, modal]);\n }\n\n /**\n * Unregisters a modal instance from the stack service.\n * @param modal - The modal component to unregister\n * @public\n */\n unregister(modal: NgxCustomModalComponent): void {\n this.modals.update(modals => modals.filter(m => m !== modal));\n }\n\n /**\n * Determines if the given modal is the topmost visible modal.\n * Used for proper event handling and accessibility.\n * @param modal - The modal instance to check\n * @returns {boolean} True if the modal is topmost\n * @public\n */\n isTopMost(modal: NgxCustomModalComponent): boolean {\n const modals = this.modals();\n const visibleModals = modals.filter(m => m.visible());\n return visibleModals[visibleModals.length - 1] === modal;\n }\n\n /**\n * Calculates the next z-index value for a new modal.\n * Each modal gets a z-index 10 units higher than the previous.\n * @returns {number} The z-index value to use\n * @public\n */\n getNextZIndex(): number {\n const visibleCount = this.modals().filter(m => m.visible()).length;\n return this.baseZIndex + visibleCount * 10;\n }\n\n /**\n * Gets the count of currently active (visible) modals.\n * @returns {number} Number of active modals\n * @public\n */\n getActiveModalsCount(): number {\n return this.modals().filter(m => m.visible()).length;\n }\n}\n","import { Injectable, VERSION } from '@angular/core';\n\nexport interface AfterRenderCallback {\n (): void;\n}\n\nexport interface AfterRenderOptions {\n phase?: any;\n injector?: any;\n}\n\n/**\n * Service to handle lifecycle hook compatibility across Angular versions.\n * Manages the breaking change from afterRender to afterEveryRender in Angular 20.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class LifecycleCompatibilityService {\n private readonly majorVersion = parseInt(VERSION.major);\n private readonly minorVersion = parseInt(VERSION.minor);\n\n /**\n * Ejecuta un callback después de cada render (compatible entre versiones).\n */\n public afterEveryRender(callback: AfterRenderCallback, options?: AfterRenderOptions): (() => void) | null {\n try {\n // Intentar usar la función apropiada según la versión\n if (this.majorVersion >= 20) {\n // Para Angular 20+, intentar afterEveryRender\n const afterEveryRender = (globalThis as any)?.ng?.core?.afterEveryRender;\n if (afterEveryRender) {\n return afterEveryRender(callback, options);\n }\n } else if (this.majorVersion >= 17 || (this.majorVersion === 16 && this.minorVersion >= 2)) {\n // Para Angular 16.2-19, intentar afterRender\n const afterRender = (globalThis as any)?.ng?.core?.afterRender;\n if (afterRender) {\n return afterRender(callback, options);\n }\n }\n } catch (error) {\n console.warn('Error executing lifecycle hook:', error);\n }\n\n // Fallback usando requestAnimationFrame o setTimeout\n this.fallbackAfterRender(callback);\n return null;\n }\n\n /**\n * Ejecuta un callback después del siguiente render.\n */\n public afterNextRender(callback: AfterRenderCallback, options?: AfterRenderOptions): (() => void) | null {\n try {\n const afterNextRender = (globalThis as any)?.ng?.core?.afterNextRender;\n if (afterNextRender) {\n return afterNextRender(callback, options);\n }\n } catch (error) {\n console.warn('Error executing afterNextRender hook:', error);\n }\n\n // Fallback usando requestAnimationFrame o setTimeout\n this.fallbackAfterNextRender(callback);\n return null;\n }\n\n /**\n * Implementación de fallback para afterRender.\n */\n private fallbackAfterRender(callback: AfterRenderCallback): void {\n if (typeof requestAnimationFrame !== 'undefined') {\n requestAnimationFrame(() => {\n try {\n callback();\n } catch (error) {\n console.warn('Error in fallback afterRender callback:', error);\n }\n });\n } else {\n setTimeout(() => {\n try {\n callback();\n } catch (error) {\n console.warn('Error in fallback afterRender callback:', error);\n }\n }, 0);\n }\n }\n\n /**\n * Implementación de fallback para afterNextRender.\n */\n private fallbackAfterNextRender(callback: AfterRenderCallback): void {\n this.fallbackAfterRender(callback);\n }\n\n /**\n * Retorna información sobre la versión actual.\n */\n public getVersionInfo(): {\n major: number;\n minor: number;\n patch: string;\n hasAfterRender: boolean;\n hasAfterNextRender: boolean;\n hookName: string;\n } {\n return {\n major: this.majorVersion,\n minor: this.minorVersion,\n patch: VERSION.patch,\n hasAfterRender: true, // Siempre disponible mediante fallback\n hasAfterNextRender: true, // Siempre disponible mediante fallback\n hookName: this.majorVersion >= 20 ? 'afterEveryRender' : 'afterRender',\n };\n }\n}\n","import { CommonModule } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n ContentChild,\n effect,\n ElementRef,\n EventEmitter,\n HostListener,\n inject,\n Input,\n OnDestroy,\n OnInit,\n Output,\n signal,\n TemplateRef,\n ViewChild,\n} from '@angular/core';\nimport { ModalOptions, ModalState } from './modal-options.interface';\nimport { NgxModalStackService } from './ngx-modal-stack.service';\nimport { LifecycleCompatibilityService } from './compatibility/lifecycle-compatibility.service';\n\n/**\n * A feature-rich, accessible modal component for Angular 17+ applications.\n *\n * Features:\n * - Signal-based reactivity for optimal performance\n * - Advanced modal stacking with z-index management\n * - Full WCAG accessibility compliance\n * - Bootstrap 3, 4 & 5 compatibility\n * - Touch-optimized for mobile devices\n * - Customizable animations and styling\n * - Cross-version compatibility (Angular 17-20+)\n *\n * @example\n * ```html\n * <ngx-custom-modal #modal [size]=\"'lg'\" [centered]=\"true\">\n * <ng-template #modalHeader>\n * <h2>Modal Title</h2>\n * </ng-template>\n * <ng-template #modalBody>\n * <p>Modal content</p>\n * </ng-template>\n * </ngx-custom-modal>\n * ```\n *\n * @public\n */\n@Component({\n selector: 'ngx-custom-modal',\n standalone: true,\n imports: [CommonModule],\n templateUrl: './ngx-custom-modal.component.html',\n styleUrls: ['./ngx-custom-modal.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class NgxCustomModalComponent implements OnInit, OnDestroy {\n private elementRef = inject(ElementRef);\n private document = inject(Document, { optional: true });\n private lifecycleService = inject(LifecycleCompatibilityService);\n\n @ViewChild('modalDialog', { static: false }) modalDialog!: ElementRef<HTMLDialogElement>;\n\n /** Template reference for modal header content */\n @ContentChild('modalHeader') header: TemplateRef<any> | null = null;\n\n /** Template reference for modal body content */\n @ContentChild('modalBody') body: TemplateRef<any> | null = null;\n\n /** Template reference for modal footer content */\n @ContentChild('modalFooter') footer: TemplateRef<any> | null = null;\n\n /** Close modal when clicking outside the modal content. @default true */\n @Input() closeOnOutsideClick = true;\n\n /** Close modal when pressing the Escape key. @default true */\n @Input() closeOnEscape = true;\n\n /** Additional CSS class to apply to the modal container */\n @Input() customClass?: string;\n\n /** Hide the default close button (×) in the header. @default false */\n @Input() hideCloseButton = false;\n\n /** Configuration options object that overrides individual properties */\n @Input() options: ModalOptions = {};\n\n /** Modal size preset. @default 'md' */\n @Input() size: 'sm' | 'md' | 'lg' | 'xl' = 'md';\n\n /** Center modal vertically in viewport. @default false */\n @Input() centered = false;\n\n /** Make modal body scrollable when content overflows. @default false */\n @Input() scrollable = false;\n\n /** Enable CSS transition animations. @default true */\n @Input() animation = true;\n\n /** Backdrop behavior configuration. @default 'dynamic' */\n @Input() backdrop: 'static' | 'dynamic' = 'dynamic';\n\n /** Enable keyboard interactions. @default true */\n @Input() keyboard = true;\n\n /** Enable automatic focus management. @default true */\n @Input() focus = true;\n\n /** Emitted when modal starts opening */\n @Output() opened = new EventEmitter<void>();\n\n /** Emitted when modal is fully closed */\n @Output() closed = new EventEmitter<void>();\n\n /** Emitted before modal starts opening */\n @Output() opening = new EventEmitter<void>();\n\n /** Emitted before modal starts closing */\n @Output() closing = new EventEmitter<void>();\n\n private modalState = signal<ModalState>({\n isVisible: false,\n isAnimating: false,\n zIndex: 1050,\n previousFocusedElement: undefined,\n });\n\n private animationDuration = signal<number>(200);\n private modalStack = signal<NgxCustomModalComponent[]>([]);\n\n /** Computed signal for modal visibility state */\n visible = computed(() => this.modalState().isVisible);\n\n /** Signal for animation state */\n visibleAnimate = signal<boolean>(false);\n\n /** Computed signal for animation state */\n isAnimating = computed(() => this.modalState().isAnimating);\n\n /** Unique ID for modal title (ARIA) */\n titleId = signal(`modal-title-${Math.random().toString(36).substr(2, 9)}`);\n\n /** Unique ID for modal description (ARIA) */\n descriptionId = signal(`modal-desc-${Math.random().toString(36).substr(2, 9)}`);\n\n private previouslyFocusedElement: HTMLElement | null = null;\n private modalStackService = inject(NgxModalStackService, { optional: true });\n private afterRenderCleanup: (() => void) | null = null;\n private afterNextRenderCleanup: (() => void) | null = null;\n\n constructor() {\n // Effect to handle modal visibility changes\n effect(() => {\n const isVisible = this.visible();\n if (isVisible) {\n this.handleModalOpen();\n } else {\n this.handleModalClose();\n }\n });\n\n // Effect to handle animation duration changes\n effect(() => {\n const duration = this.options.animationDuration || 200;\n this.animationDuration.set(duration);\n this.updateCSSAnimationDuration(duration);\n });\n\n // Setup lifecycle hooks with compatibility\n this.setupLifecycleHooks();\n }\n\n ngOnInit(): void {\n this.registerInModalStack();\n this.logVersionInfo();\n }\n\n ngOnDestroy(): void {\n this.close();\n this.unregisterFromModalStack();\n this.restoreFocus();\n this.removeBodyClass();\n this.cleanupLifecycleHooks();\n }\n\n /**\n * Opens the modal with proper accessibility and focus management.\n *\n * Automatically handles:\n * - Focus management (saves current focus, sets focus to modal)\n * - Body scroll locking\n * - Z-index management for stacking\n * - Screen reader announcements\n *\n * @public\n * @fires opening - Before modal animation starts\n * @fires opened - After modal is fully visible\n */\n open(): void {\n if (this.visible()) return;\n\n this.opening.emit();\n this.storePreviousFocus();\n this.addBodyClass();\n\n this.modalState.update(state => ({\n ...state,\n isVisible: true,\n isAnimating: true,\n }));\n\n if (this.animation) {\n setTimeout(() => {\n this.visibleAnimate.set(true);\n this.modalState.update(state => ({ ...state, isAnimating: false }));\n this.focusFirstElement();\n this.opened.emit();\n }, 10);\n } else {\n this.visibleAnimate.set(true);\n this.modalState.update(state => ({ ...state, isAnimating: false }));\n this.focusFirstElement();\n this.opened.emit();\n }\n }\n\n /**\n * Closes the modal and restores previous state.\n *\n * Automatically handles:\n * - Focus restoration to previously focused element\n * - Body scroll unlock (if no other modals open)\n * - Cleanup of event listeners\n *\n * @public\n * @fires closing - Before modal animation starts\n * @fires closed - After modal is fully hidden\n */\n close(): void {\n if (!this.visible()) return;\n\n this.closing.emit();\n\n this.modalState.update(state => ({\n ...state,\n isAnimating: true,\n }));\n\n this.visibleAnimate.set(false);\n\n const duration = this.animation ? this.animationDuration() : 0;\n\n setTimeout(() => {\n this.modalState.update(state => ({\n ...state,\n isVisible: false,\n isAnimating: false,\n }));\n\n this.removeBodyClass();\n this.restoreFocus();\n this.closed.emit();\n }, duration);\n }\n\n /**\n * Toggles the modal visibility state.\n * @public\n */\n toggle(): void {\n if (this.visible()) {\n this.close();\n } else {\n this.open();\n }\n }\n\n /**\n * Handles clicks on the modal container for outside click detection.\n * @param event - The mouse click event\n * @private\n */\n @HostListener('click', ['$event'])\n onContainerClicked(event: MouseEvent): void {\n const closeOnOutsideClick = this.options.closeOnOutsideClick ?? this.closeOnOutsideClick;\n const backdrop = this.options.backdrop || this.backdrop;\n\n if (\n (event.target as HTMLElement).classList.contains('modal') &&\n this.isTopMost() &&\n closeOnOutsideClick &&\n backdrop === 'dynamic'\n ) {\n this.close();\n }\n }\n\n /**\n * Handles global keyboard events for modal functionality.\n * @param event - The keyboard event\n * @private\n */\n @HostListener('document:keydown', ['$event'])\n onKeyDownHandler(event: KeyboardEvent): void {\n if (!this.visible() || !this.isTopMost()) return;\n\n const closeOnEscape = this.options.closeOnEscape ?? this.closeOnEscape;\n const keyboardEnabled = this.options.keyboard ?? this.keyboard;\n\n if (event.key === 'Escape' && closeOnEscape && keyboardEnabled) {\n this.close();\n } else if (event.key === 'Tab') {\n this.handleTabKey(event);\n }\n }\n\n /**\n * Checks if this modal is the topmost in the stack.\n * Used for proper event handling in nested modals.\n *\n * @returns {boolean} True if this modal is on top of the stack\n * @public\n */\n isTopMost(): boolean {\n if (this.modalStackService) {\n return this.modalStackService.isTopMost(this);\n }\n return !this.elementRef.nativeElement.querySelector(':scope ngx-custom-modal > .modal');\n }\n\n /**\n * Gets the combined custom CSS classes for the modal.\n * @returns {string} Space-separated CSS classes\n * @public\n */\n getCustomClass(): string {\n const customClass = this.customClass ?? this.options.customClass ?? '';\n const sizeClass = this.getSizeClass();\n const animationClass = this.getAnimationClass();\n\n return [customClass, sizeClass, animationClass].filter(Boolean).join(' ');\n }\n\n /**\n * Gets the CSS classes for the modal dialog container.\n * @returns {string} Space-separated CSS classes\n * @public\n */\n getDialogClasses(): string {\n const classes: string[] = [];\n\n if (this.centered || this.options.centered) {\n classes.push('modal-dialog-centered');\n }\n\n if (this.scrollable || this.options.scrollable) {\n classes.push('modal-dialog-scrollable');\n }\n\n const size = this.options.size || this.size;\n if (size && size !== 'md') {\n classes.push(`modal-${size}`);\n }\n\n return classes.join(' ');\n }\n\n /**\n * Determines if the close button should be hidden.\n * @returns {boolean} True if close button should be hidden\n * @public\n */\n shouldHideCloseButton(): boolean {\n return this.hideCloseButton || this.options.hideCloseButton || false;\n }\n\n /**\n * Gets the ARIA label for the close button.\n * @returns {string} Localized close button label\n * @public\n */\n getCloseButtonLabel(): string {\n return 'Close modal';\n }\n\n /**\n * Checks if header content is available.\n * @returns {boolean} True if header template exists\n * @public\n */\n hasHeaderContent(): boolean {\n return !!this.header;\n }\n\n /**\n * Checks if footer content is available.\n * @returns {boolean} True if footer template exists\n * @public\n */\n hasFooterContent(): boolean {\n return !!this.footer;\n }\n\n /**\n * Sets up lifecycle hooks with version compatibility.\n * @private\n */\n private setupLifecycleHooks(): void {\n // Setup afterNextRender for initial setup\n this.afterNextRenderCleanup = this.lifecycleService.afterNextRender(() => {\n this.setupAccessibility();\n this.setupKeyboardNavigation();\n this.setupFocusManagement();\n });\n\n // Setup afterEveryRender for ongoing updates\n this.afterRenderCleanup = this.lifecycleService.afterEveryRender(() => {\n if (this.visible() && this.modalDialog) {\n this.adjustModalPosition();\n this.ensureProperZIndex();\n }\n });\n }\n\n /**\n * Cleans up lifecycle hook subscriptions.\n * @private\n */\n private cleanupLifecycleHooks(): void {\n if (this.afterRenderCleanup) {\n this.afterRenderCleanup();\n this.afterRenderCleanup = null;\n }\n if (this.afterNextRenderCleanup) {\n this.afterNextRenderCleanup();\n this.afterNextRenderCleanup = null;\n }\n }\n\n /**\n * Logs version information for debugging.\n * @private\n */\n private logVersionInfo(): void {\n const versionInfo = this.lifecycleService.getVersionInfo();\n console.log(`[NgxCustomModal] Angular ${versionInfo.major}.${versionInfo.minor}.${versionInfo.patch}`);\n console.log(`[NgxCustomModal] Using lifecycle hook: ${versionInfo.hookName}`);\n console.log(\n `[NgxCustomModal] Hooks available - afterRender: ${versionInfo.hasAfterRender}, afterNextRender: ${versionInfo.hasAfterNextRender}`\n );\n }\n\n /**\n * Handles modal opening side effects.\n * @private\n */\n private handleModalOpen(): void {\n this.previouslyFocusedElement = this.document?.activeElement as HTMLElement;\n this.announceToScreenReader('Modal opened');\n }\n\n /**\n * Handles modal closing side effects.\n * @private\n */\n private handleModalClose(): void {\n this.announceToScreenReader('Modal closed');\n }\n\n /**\n * Sets up accessibility attributes and ARIA labels.\n * @private\n */\n private setupAccessibility(): void {\n const modalElement = this.elementRef.nativeElement.querySelector('.modal');\n if (modalElement) {\n modalElement.setAttribute('role', 'dialog');\n modalElement.setAttribute('aria-modal', 'true');\n }\n }\n\n /**\n * Sets up keyboard navigation handlers.\n * @private\n */\n private setupKeyboardNavigation(): void {\n // Keyboard navigation is handled in the @HostListener\n }\n\n /**\n * Sets up focus management systems.\n * @private\n */\n private setupFocusManagement(): void {\n // Focus management is handled in focusFirstElement and restoreFocus methods\n }\n\n /**\n * Adjusts modal position and size based on viewport.\n * @private\n */\n private adjustModalPosition(): void {\n const modalDialog = this.elementRef.nativeElement.querySelector('.modal-dialog');\n if (modalDialog) {\n const rect = modalDialog.getBoundingClientRect();\n if (rect.height > window.innerHeight * 0.9) {\n modalDialog.style.height = `${window.innerHeight * 0.9}px`;\n }\n }\n }\n\n /**\n * Ensures proper z-index for modal stacking.\n * @private\n */\n private ensureProperZIndex(): void {\n const modalElement = this.elementRef.nativeElement.querySelector('.modal') as HTMLElement;\n if (modalElement && this.modalStackService) {\n const zIndex = this.modalStackService.getNextZIndex();\n modalElement.style.zIndex = zIndex.toString();\n\n this.modalState.update(state => ({\n ...state,\n zIndex,\n }));\n }\n }\n\n /**\n * Stores the currently focused element for later restoration.\n * @private\n */\n private storePreviousFocus(): void {\n this.previouslyFocusedElement = this.document?.activeElement as HTMLElement;\n\n this.modalState.update(state => ({\n ...state,\n previousFocusedElement: this.previouslyFocusedElement || undefined,\n }));\n }\n\n /**\n * Restores focus to the previously focused element.\n * @private\n */\n private restoreFocus(): void {\n if (this.previouslyFocusedElement && this.focus) {\n setTimeout(() => {\n this.previouslyFocusedElement?.focus();\n }, 0);\n }\n }\n\n /**\n * Manages focus within the modal for accessibility.\n * Focuses first focusable element or close button as fallback.\n * @private\n */\n private focusFirstElement(): void {\n if (!this.focus) return;\n\n setTimeout(() => {\n const modalElement = this.elementRef.nativeElement.querySelector('.modal');\n const firstFocusable = modalElement?.querySelector(\n 'button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), a[href], [tabindex]:not([tabindex=\"-1\"])'\n ) as HTMLElement;\n\n if (firstFocusable) {\n firstFocusable.focus();\n } else {\n const closeButton = modalElement?.querySelector('.close') as HTMLElement;\n closeButton?.focus();\n }\n }, 0);\n }\n\n /**\n * Handles tab key navigation to trap focus within the modal.\n * Implements circular focus trapping as per WCAG guidelines.\n * @param event - The keyboard event\n * @private\n */\n private handleTabKey(event: KeyboardEvent): void {\n const modalElement = this.elementRef.nativeElement.querySelector('.modal');\n if (!modalElement) return;\n\n const focusableElements = Array.from(\n modalElement.querySelectorAll(\n 'button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), a[href], [tabindex]:not([tabindex=\"-1\"])'\n )\n ) as HTMLElement[];\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n if (event.shiftKey) {\n if (this.document?.activeElement === firstElement) {\n event.preventDefault();\n lastElement?.focus();\n }\n } else {\n if (this.document?.activeElement === lastElement) {\n event.preventDefault();\n firstElement?.focus();\n }\n }\n }\n\n /**\n * Adds modal-open class to body to prevent scrolling.\n * @private\n */\n private addBodyClass(): void {\n this.document?.body.classList.add('modal-open');\n }\n\n /**\n * Removes modal-open class from body when no modals are open.\n * @private\n */\n private removeBodyClass(): void {\n if (this.modalStackService?.getActiveModalsCount() === 0) {\n this.document?.body.classList.remove('modal-open');\n }\n }\n\n /**\n * Gets the CSS class for modal size.\n * @returns {string} Size-specific CSS class\n * @private\n */\n private getSizeClass(): string {\n const size = this.options.size || this.size;\n return size && size !== 'md' ? `modal-${size}` : '';\n }\n\n /**\n * Gets the CSS class for animation state.\n * @returns {string} Animation-specific CSS class\n * @private\n */\n private getAnimationClass(): string {\n const hasAnimation = this.options.animation ?? this.animation;\n return hasAnimation ? 'modal-animated' : 'modal-no-animation';\n }\n\n /**\n * Updates CSS custom property for animation duration.\n * @param duration - Animation duration in milliseconds\n * @private\n */\n private updateCSSAnimationDuration(duration: number): void {\n const modalElement = this.elementRef.nativeElement.querySelector('.modal') as HTMLElement;\n if (modalElement) {\n modalElement.style.setProperty('--modal-animation-duration', `${duration}ms`);\n }\n }\n\n /**\n * Registers this modal instance with the modal stack service.\n * @private\n */\n private registerInModalStack(): void {\n this.modalStackService?.register(this);\n }\n\n /**\n * Unregisters this modal instance from the modal stack service.\n * @private\n */\n private unregisterFromModalStack(): void {\n this.modalStackService?.unregister(this);\n }\n\n /**\n * Announces messages to screen readers for accessibility.\n * @param message - Message to announce\n * @private\n */\n private announceToScreenReader(message: string): void {\n const announcement = this.document?.createElement('div');\n if (!announcement) return;\n\n announcement.setAttribute('aria-live', 'polite');\n announcement.setAttribute('aria-atomic', 'true');\n announcement.className = 'sr-only visually-hidden';\n announcement.style.position = 'absolute';\n announcement.style.left = '-10000px';\n announcement.style.width = '1px';\n announcement.style.height = '1px';\n announcement.style.overflow = 'hidden';\n announcement.textContent = message;\n\n this.document?.body.appendChild(announcement);\n\n setTimeout(() => {\n this.document?.body.removeChild(announcement);\n }, 1000);\n }\n}\n","<!-- ./projects/ngx-custom-modal/src/lib/ngx-custom-modal.component.html -->\n\n<!--\n Main modal container with conditional rendering using Angular 17+ control flow.\n Uses signals for reactive visibility state and implements WCAG accessibility standards.\n-->\n@if (visible()) {\n <div\n class=\"modal fade\"\n role=\"dialog\"\n tabindex=\"-1\"\n [class.in]=\"visibleAnimate()\"\n [ngClass]=\"getCustomClass()\"\n [attr.aria-modal]=\"true\"\n [attr.aria-labelledby]=\"titleId()\"\n [attr.aria-describedby]=\"descriptionId()\"\n >\n <div class=\"modal-dialog\" [ngClass]=\"getDialogClasses()\">\n <div class=\"modal-content\">\n <!-- Header section with conditional close button -->\n @if (header || hasHeaderContent()) {\n <div class=\"modal-header\">\n <!-- User-provided header content via ng-template -->\n <ng-container *ngTemplateOutlet=\"header\"></ng-container>\n\n <!-- Close button respects hideCloseButton setting and options -->\n @if (!shouldHideCloseButton()) {\n <button class=\"close\" type=\"button\" [attr.aria-label]=\"getCloseButtonLabel()\" (click)=\"close()\">\n <span aria-hidden=\"true\">×</span>\n </button>\n }\n </div>\n }\n\n <!-- Body section with proper ARIA labeling for screen readers -->\n @if (body) {\n <div class=\"modal-body\" [id]=\"descriptionId()\">\n <!-- User-provided body content via ng-template -->\n <ng-container *ngTemplateOutlet=\"body\"></ng-container>\n </div>\n }\n\n <!-- Footer section for action buttons and additional content -->\n @if (footer || hasFooterContent()) {\n <div class=\"modal-footer\">\n <!-- User-provided footer content via ng-template -->\n <ng-container *ngTemplateOutlet=\"footer\"></ng-container>\n </div>\n }\n </div>\n </div>\n </div>\n}\n","// ./projects/ngx-custom-modal/src/public-api.ts\n\n/**\n * @fileoverview Public API for ngx-custom-modal library\n *\n * This file defines what is exported from the library and available\n * for consumers to import. All exports are carefully curated to provide\n * a clean and stable API surface.\n *\n * @version 20.0.0\n * @author Angel Careaga <dev.angelcareaga@gmail.com>\n */\n\n/**\n * Core modal component and stack management service.\n * These are the primary exports that most users will need.\n */\nexport { NgxCustomModalComponent } from './lib/ngx-custom-modal.component';\nexport { NgxModalStackService } from './lib/ngx-modal-stack.service';\n\n/**\n * Type definitions for configuration and customization.\n * These interfaces provide strong typing for modal options and state.\n */\nexport { ModalOptions, ModalButton, ModalState } from './lib/modal-options.interface';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}