UNPKG

ngx-custom-modal

Version:

A custom Modal / Dialog (with inner component support) for Angular 17-20 projects with full version compatibility

432 lines (427 loc) 14.5 kB
import * as _angular_core from '@angular/core'; import { OnInit, OnDestroy, ElementRef, TemplateRef, EventEmitter } from '@angular/core'; /** * Configuration options for the ngx-custom-modal component. * @public */ interface ModalOptions { /** Close modal when clicking outside the modal content. @default true */ closeOnOutsideClick?: boolean; /** Close modal when pressing the Escape key. @default true */ closeOnEscape?: boolean; /** Additional CSS class to apply to the modal container */ customClass?: string; /** Hide the default close button (×) in the header. @default false */ hideCloseButton?: boolean; /** * Backdrop behavior configuration * - 'static': Prevents closing when clicking outside * - 'dynamic': Allows closing when clicking outside (if closeOnOutsideClick is true) * @default 'dynamic' */ backdrop?: 'static' | 'dynamic'; /** Enable keyboard interactions (Tab navigation, Escape key). @default true */ keyboard?: boolean; /** Enable automatic focus management. @default true */ focus?: boolean; /** * Modal size preset * - 'sm': Small (300px max-width) * - 'md': Medium (500px max-width) * - 'lg': Large (800px max-width) * - 'xl': Extra Large (1140px max-width) * @default 'md' */ size?: 'sm' | 'md' | 'lg' | 'xl'; /** Center modal vertically in viewport. @default false */ centered?: boolean; /** Make modal body scrollable when content overflows. @default false */ scrollable?: boolean; /** Enable CSS transition animations. @default true */ animation?: boolean; /** Animation duration in milliseconds. @default 200 */ animationDuration?: number; } /** * Button configuration for modal footers. * @public */ interface ModalButton { /** Unique identifier for the button */ id: string; /** Display text for the button */ text: string; /** CSS classes to apply to the button */ class: string; /** HTML button type attribute. @default 'button' */ type?: 'button' | 'submit' | 'reset'; /** Click event handler function */ handler?: () => void; /** Disable the button. @default false */ disabled?: boolean; } /** * Internal state interface for modal component. * Used by signals for reactive state management. * @internal */ interface ModalState { /** Whether the modal is currently visible */ isVisible: boolean; /** Whether the modal is currently animating (opening/closing) */ isAnimating: boolean; /** Current z-index value for stacking */ zIndex: number; /** Element that had focus before modal opened (for restoration) */ previousFocusedElement?: HTMLElement; } /** * A feature-rich, accessible modal component for Angular 17+ applications. * * Features: * - Signal-based reactivity for optimal performance * - Advanced modal stacking with z-index management * - Full WCAG accessibility compliance * - Bootstrap 3, 4 & 5 compatibility * - Touch-optimized for mobile devices * - Customizable animations and styling * - Cross-version compatibility (Angular 17-20+) * * @example * ```html * <ngx-custom-modal #modal [size]="'lg'" [centered]="true"> * <ng-template #modalHeader> * <h2>Modal Title</h2> * </ng-template> * <ng-template #modalBody> * <p>Modal content</p> * </ng-template> * </ngx-custom-modal> * ``` * * @public */ declare class NgxCustomModalComponent implements OnInit, OnDestroy { private elementRef; private document; private lifecycleService; modalDialog: ElementRef<HTMLDialogElement>; /** Template reference for modal header content */ header: TemplateRef<any> | null; /** Template reference for modal body content */ body: TemplateRef<any> | null; /** Template reference for modal footer content */ footer: TemplateRef<any> | null; /** Close modal when clicking outside the modal content. @default true */ closeOnOutsideClick: boolean; /** Close modal when pressing the Escape key. @default true */ closeOnEscape: boolean; /** Additional CSS class to apply to the modal container */ customClass?: string; /** Hide the default close button (×) in the header. @default false */ hideCloseButton: boolean; /** Configuration options object that overrides individual properties */ options: ModalOptions; /** Modal size preset. @default 'md' */ size: 'sm' | 'md' | 'lg' | 'xl'; /** Center modal vertically in viewport. @default false */ centered: boolean; /** Make modal body scrollable when content overflows. @default false */ scrollable: boolean; /** Enable CSS transition animations. @default true */ animation: boolean; /** Backdrop behavior configuration. @default 'dynamic' */ backdrop: 'static' | 'dynamic'; /** Enable keyboard interactions. @default true */ keyboard: boolean; /** Enable automatic focus management. @default true */ focus: boolean; /** Emitted when modal starts opening */ opened: EventEmitter<void>; /** Emitted when modal is fully closed */ closed: EventEmitter<void>; /** Emitted before modal starts opening */ opening: EventEmitter<void>; /** Emitted before modal starts closing */ closing: EventEmitter<void>; private modalState; private animationDuration; private modalStack; /** Computed signal for modal visibility state */ visible: _angular_core.Signal<boolean>; /** Signal for animation state */ visibleAnimate: _angular_core.WritableSignal<boolean>; /** Computed signal for animation state */ isAnimating: _angular_core.Signal<boolean>; /** Unique ID for modal title (ARIA) */ titleId: _angular_core.WritableSignal<string>; /** Unique ID for modal description (ARIA) */ descriptionId: _angular_core.WritableSignal<string>; private previouslyFocusedElement; private modalStackService; private afterRenderCleanup; private afterNextRenderCleanup; constructor(); ngOnInit(): void; ngOnDestroy(): void; /** * Opens the modal with proper accessibility and focus management. * * Automatically handles: * - Focus management (saves current focus, sets focus to modal) * - Body scroll locking * - Z-index management for stacking * - Screen reader announcements * * @public * @fires opening - Before modal animation starts * @fires opened - After modal is fully visible */ open(): void; /** * Closes the modal and restores previous state. * * Automatically handles: * - Focus restoration to previously focused element * - Body scroll unlock (if no other modals open) * - Cleanup of event listeners * * @public * @fires closing - Before modal animation starts * @fires closed - After modal is fully hidden */ close(): void; /** * Toggles the modal visibility state. * @public */ toggle(): void; /** * Handles clicks on the modal container for outside click detection. * @param event - The mouse click event * @private */ onContainerClicked(event: MouseEvent): void; /** * Handles global keyboard events for modal functionality. * @param event - The keyboard event * @private */ onKeyDownHandler(event: KeyboardEvent): void; /** * Checks if this modal is the topmost in the stack. * Used for proper event handling in nested modals. * * @returns {boolean} True if this modal is on top of the stack * @public */ isTopMost(): boolean; /** * Gets the combined custom CSS classes for the modal. * @returns {string} Space-separated CSS classes * @public */ getCustomClass(): string; /** * Gets the CSS classes for the modal dialog container. * @returns {string} Space-separated CSS classes * @public */ getDialogClasses(): string; /** * Determines if the close button should be hidden. * @returns {boolean} True if close button should be hidden * @public */ shouldHideCloseButton(): boolean; /** * Gets the ARIA label for the close button. * @returns {string} Localized close button label * @public */ getCloseButtonLabel(): string; /** * Checks if header content is available. * @returns {boolean} True if header template exists * @public */ hasHeaderContent(): boolean; /** * Checks if footer content is available. * @returns {boolean} True if footer template exists * @public */ hasFooterContent(): boolean; /** * Sets up lifecycle hooks with version compatibility. * @private */ private setupLifecycleHooks; /** * Cleans up lifecycle hook subscriptions. * @private */ private cleanupLifecycleHooks; /** * Logs version information for debugging. * @private */ private logVersionInfo; /** * Handles modal opening side effects. * @private */ private handleModalOpen; /** * Handles modal closing side effects. * @private */ private handleModalClose; /** * Sets up accessibility attributes and ARIA labels. * @private */ private setupAccessibility; /** * Sets up keyboard navigation handlers. * @private */ private setupKeyboardNavigation; /** * Sets up focus management systems. * @private */ private setupFocusManagement; /** * Adjusts modal position and size based on viewport. * @private */ private adjustModalPosition; /** * Ensures proper z-index for modal stacking. * @private */ private ensureProperZIndex; /** * Stores the currently focused element for later restoration. * @private */ private storePreviousFocus; /** * Restores focus to the previously focused element. * @private */ private restoreFocus; /** * Manages focus within the modal for accessibility. * Focuses first focusable element or close button as fallback. * @private */ private focusFirstElement; /** * Handles tab key navigation to trap focus within the modal. * Implements circular focus trapping as per WCAG guidelines. * @param event - The keyboard event * @private */ private handleTabKey; /** * Adds modal-open class to body to prevent scrolling. * @private */ private addBodyClass; /** * Removes modal-open class from body when no modals are open. * @private */ private removeBodyClass; /** * Gets the CSS class for modal size. * @returns {string} Size-specific CSS class * @private */ private getSizeClass; /** * Gets the CSS class for animation state. * @returns {string} Animation-specific CSS class * @private */ private getAnimationClass; /** * Updates CSS custom property for animation duration. * @param duration - Animation duration in milliseconds * @private */ private updateCSSAnimationDuration; /** * Registers this modal instance with the modal stack service. * @private */ private registerInModalStack; /** * Unregisters this modal instance from the modal stack service. * @private */ private unregisterFromModalStack; /** * Announces messages to screen readers for accessibility. * @param message - Message to announce * @private */ private announceToScreenReader; static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgxCustomModalComponent, never>; static ɵcmp: _angular_core.ɵɵComponentDeclaration<NgxCustomModalComponent, "ngx-custom-modal", never, { "closeOnOutsideClick": { "alias": "closeOnOutsideClick"; "required": false; }; "closeOnEscape": { "alias": "closeOnEscape"; "required": false; }; "customClass": { "alias": "customClass"; "required": false; }; "hideCloseButton": { "alias": "hideCloseButton"; "required": false; }; "options": { "alias": "options"; "required": false; }; "size": { "alias": "size"; "required": false; }; "centered": { "alias": "centered"; "required": false; }; "scrollable": { "alias": "scrollable"; "required": false; }; "animation": { "alias": "animation"; "required": false; }; "backdrop": { "alias": "backdrop"; "required": false; }; "keyboard": { "alias": "keyboard"; "required": false; }; "focus": { "alias": "focus"; "required": false; }; }, { "opened": "opened"; "closed": "closed"; "opening": "opening"; "closing": "closing"; }, ["header", "body", "footer"], never, true, never>; } /** * Service for managing multiple modal instances and their stacking order. * * Handles: * - Z-index calculation for proper stacking * - Modal registration/unregistration * - Top-most modal identification * - Body class management * * @injectable * @public */ declare class NgxModalStackService { private modals; private baseZIndex; /** * Registers a modal instance with the stack service. * @param modal - The modal component to register * @public */ register(modal: NgxCustomModalComponent): void; /** * Unregisters a modal instance from the stack service. * @param modal - The modal component to unregister * @public */ unregister(modal: NgxCustomModalComponent): void; /** * Determines if the given modal is the topmost visible modal. * Used for proper event handling and accessibility. * @param modal - The modal instance to check * @returns {boolean} True if the modal is topmost * @public */ isTopMost(modal: NgxCustomModalComponent): boolean; /** * Calculates the next z-index value for a new modal. * Each modal gets a z-index 10 units higher than the previous. * @returns {number} The z-index value to use * @public */ getNextZIndex(): number; /** * Gets the count of currently active (visible) modals. * @returns {number} Number of active modals * @public */ getActiveModalsCount(): number; static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgxModalStackService, never>; static ɵprov: _angular_core.ɵɵInjectableDeclaration<NgxModalStackService>; } export { NgxCustomModalComponent, NgxModalStackService }; export type { ModalButton, ModalOptions, ModalState };