Gathering detailed insights and metrics for ngx-custom-modal
Gathering detailed insights and metrics for ngx-custom-modal
Gathering detailed insights and metrics for ngx-custom-modal
Gathering detailed insights and metrics for ngx-custom-modal
ngx-modal-ease
ngx-modal-ease is a versatile Angular library providing a lightweight, simple, and performant modal. This library supports data communication between components, opening of multiple modals, custom animations, and a range of customisable options.
ngx-modal-dialog-custom
Dynamic modal dialog for Angular
ngx-bootstrap-modal-custom
Native Angular Bootstrap Components
ngx-light-modal
Lightweight and dependency-free Angular modal package using standalone components. Supports stacking, backdrops, dynamic injection, and custom content components.
A custom Modal / Dialog (with inner component support) for Angular projects
npm install ngx-custom-modal
Typescript
Module System
Min. Node Version
Node Version
NPM Version
TypeScript (86.73%)
CSS (4.52%)
SCSS (4.01%)
HTML (2.54%)
JavaScript (1.62%)
Shell (0.58%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
MIT License
2 Stars
29 Commits
2 Forks
1 Watchers
4 Branches
2 Contributors
Updated on Jul 16, 2025
Latest Version
20.1.0
Package Id
ngx-custom-modal@20.1.0
Unpacked Size
125.42 kB
Size
28.72 kB
File Count
5
NPM Version
10.8.2
Node Version
20.19.3
Published on
Jul 12, 2025
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
1
3
A lightweight Angular modal component with signal-based reactivity and full standalone support
⚠️ IMPORTANT: Version 20.0.0 introduces significant breaking changes
✅ Full Angular 17, 18, 19 & 20 Compatibility
Before upgrading, please review the CHANGELOG.md for detailed migration instructions
z-index: 42
to Bootstrap-standard 1050+
Component | What Changed | Action Required |
---|---|---|
Custom CSS | Complete styling overhaul | Review and update custom styles |
Event Handling | New granular events (opening , opened , closing , closed ) | Update event listeners |
Testing | New signal-based testing patterns | Update test assertions |
Accessibility | Enhanced ARIA attributes | Verify accessibility implementations |
Route Behavior | Automatic modal closing on navigation (enabled by default) | Configure if different behavior needed |
👉 Read Full Migration Guide in CHANGELOG.md
1npm install ngx-custom-modal 2# or 3yarn add ngx-custom-modal 4# or 5pnpm add ngx-custom-modal
1import { NgxCustomModalComponent } from 'ngx-custom-modal'; 2 3@Component({ 4 selector: 'app-example', 5 standalone: true, 6 imports: [NgxCustomModalComponent], 7 template: ` 8 <button (click)="modal.open()">Open Modal</button> 9 10 <ngx-custom-modal #modal> 11 <ng-template #modalHeader> 12 <h2>Modal Title</h2> 13 </ng-template> 14 <ng-template #modalBody> 15 <p>Modal content goes here!</p> 16 </ng-template> 17 </ngx-custom-modal> 18 `, 19}) 20export class ExampleComponent {}
1import { Component, signal } from '@angular/core'; 2import { NgxCustomModalComponent, ModalOptions } from 'ngx-custom-modal'; 3 4@Component({ 5 selector: 'app-signal-example', 6 standalone: true, 7 imports: [NgxCustomModalComponent], 8 template: ` 9 <button (click)="modal.open()">Open Signal Modal</button> 10 11 <ngx-custom-modal 12 #modal 13 [size]="modalSize()" 14 [options]="modalOptions()" 15 (opened)="onModalOpened()" 16 (closed)="onModalClosed()" 17 > 18 <ng-template #modalHeader> 19 <h2>{{ modalTitle() }}</h2> 20 </ng-template> 21 22 <ng-template #modalBody> 23 @if (showContent()) { 24 <p>{{ modalContent() }}</p> 25 @for (item of items(); track item.id) { 26 <div class="item">{{ item.name }}</div> 27 } 28 } 29 </ng-template> 30 </ngx-custom-modal> 31 `, 32}) 33export class SignalExampleComponent { 34 modalTitle = signal('Signal-Based Modal'); 35 modalContent = signal('This modal uses Angular 17 features!'); 36 modalSize = signal<'sm' | 'md' | 'lg' | 'xl'>('lg'); 37 showContent = signal(true); 38 39 items = signal([ 40 { id: 1, name: 'Signal-based reactivity' }, 41 { id: 2, name: 'Control flow syntax' }, 42 { id: 3, name: 'Performance optimization' }, 43 ]); 44 45 modalOptions = signal<ModalOptions>({ 46 closeOnOutsideClick: true, 47 closeOnEscape: true, 48 animation: true, 49 centered: true, 50 closeOnRouteChange: true, // Default: true - automatically close on navigation 51 }); 52 53 onModalOpened() { 54 console.log('Modal opened with signals!'); 55 } 56 57 onModalClosed() { 58 console.log('Modal closed'); 59 } 60}
1@Component({ 2 template: ` 3 <button (click)="componentModal.open()">Open Component Modal</button> 4 5 <ngx-custom-modal #componentModal [size]="'lg'"> 6 <ng-template #modalHeader> 7 <h2>Component Modal</h2> 8 </ng-template> 9 <ng-template #modalBody> 10 <app-my-component [data]="componentData"></app-my-component> 11 </ng-template> 12 <ng-template #modalFooter> 13 <button (click)="componentModal.close()" class="btn btn-secondary">Close</button> 14 </ng-template> 15 </ngx-custom-modal> 16 `, 17}) 18export class ComponentModalExample { 19 componentData = { message: 'Hello from component!' }; 20}
1@Component({ 2 template: ` 3 <ngx-custom-modal #parentModal [size]="'xl'"> 4 <ng-template #modalHeader> 5 <h2>Parent Modal</h2> 6 </ng-template> 7 <ng-template #modalBody> 8 <p>This is the parent modal with automatic stack management.</p> 9 <button (click)="childModal.open()">Open Child Modal</button> 10 11 <ngx-custom-modal #childModal [size]="'md'" [centered]="true"> 12 <ng-template #modalHeader> 13 <h3>Child Modal</h3> 14 </ng-template> 15 <ng-template #modalBody> 16 <p>This is a nested modal with proper z-index handling!</p> 17 </ng-template> 18 </ngx-custom-modal> 19 </ng-template> 20 </ngx-custom-modal> 21 `, 22}) 23export class NestedModalExample {}
1@Component({ 2 template: ` 3 <ngx-custom-modal 4 #customModal 5 [closeOnOutsideClick]="false" 6 [closeOnEscape]="false" 7 [hideCloseButton]="true" 8 [size]="'lg'" 9 [centered]="true" 10 [scrollable]="true" 11 [animation]="true" 12 [closeOnRouteChange]="false" 13 customClass="my-custom-modal" 14 > 15 <ng-template #modalHeader> 16 <h2>Custom Modal</h2> 17 </ng-template> 18 <ng-template #modalBody> 19 <p>This modal has custom configuration!</p> 20 <p>It will NOT close automatically when navigating to another route.</p> 21 <button (click)="customModal.close()">Manual Close</button> 22 </ng-template> 23 </ngx-custom-modal> 24 `, 25}) 26export class CustomModalExample {}
1@Component({ 2 template: ` 3 <ngx-custom-modal #optionsModal [options]="modalOptions"> 4 <ng-template #modalHeader> 5 <h2>Options Modal</h2> 6 </ng-template> 7 <ng-template #modalBody> 8 <p>Configured via options object</p> 9 </ng-template> 10 </ngx-custom-modal> 11 `, 12}) 13export class OptionsModalExample { 14 modalOptions: ModalOptions = { 15 closeOnOutsideClick: false, 16 closeOnEscape: true, 17 customClass: 'my-modal-class', 18 hideCloseButton: false, 19 size: 'lg', 20 centered: true, 21 scrollable: false, 22 animation: true, 23 animationDuration: 300, 24 backdrop: 'dynamic', 25 keyboard: true, 26 focus: true, 27 closeOnRouteChange: true, 28 }; 29}
1@Component({ 2 template: ` 3 <!-- Modal that stays open during navigation --> 4 <ngx-custom-modal #persistentModal [closeOnRouteChange]="false"> 5 <ng-template #modalHeader> 6 <h2>Persistent Modal</h2> 7 </ng-template> 8 <ng-template #modalBody> 9 <p>This modal will remain open even when you navigate to other pages.</p> 10 <p>Useful for shopping carts, music players, or global notifications.</p> 11 </ng-template> 12 </ngx-custom-modal> 13 14 <!-- Modal that closes on navigation (default behavior) --> 15 <ngx-custom-modal #standardModal> 16 <ng-template #modalHeader> 17 <h2>Standard Modal</h2> 18 </ng-template> 19 <ng-template #modalBody> 20 <p>This modal will automatically close when navigating to other pages.</p> 21 <p>This is the default behavior for better UX.</p> 22 </ng-template> 23 </ngx-custom-modal> 24 `, 25}) 26export class RouteAwareModalExample {}
Property | Type | Default | Description |
---|---|---|---|
closeOnOutsideClick | boolean | true | Close modal when clicking outside |
closeOnEscape | boolean | true | Close modal when pressing Escape key |
customClass | string | '' | Custom CSS class for the modal |
hideCloseButton | boolean | false | Hide the default close button |
options | ModalOptions | {} | Configuration options object |
size | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Modal size |
centered | boolean | false | Center modal vertically |
scrollable | boolean | false | Make modal body scrollable |
animation | boolean | true | Enable/disable animations |
backdrop | 'static' | 'dynamic' | 'dynamic' | Backdrop behavior |
keyboard | boolean | true | Enable keyboard interactions |
focus | boolean | true | Enable focus management |
closeOnRouteChange | boolean | true | Close modal on route navigation |
Event | Type | Description |
---|---|---|
opening | EventEmitter<void> | Emitted when modal starts opening |
opened | EventEmitter<void> | Emitted when modal is fully opened |
closing | EventEmitter<void> | Emitted when modal starts closing |
closed | EventEmitter<void> | Emitted when modal is fully closed |
Template Ref | Type | Description |
---|---|---|
#modalHeader | TemplateRef | Header content template |
#modalBody | TemplateRef | Body content template |
#modalFooter | TemplateRef | Footer content template |
Method | Returns | Description |
---|---|---|
open() | void | Opens the modal |
close() | void | Closes the modal |
toggle() | void | Toggles modal visibility |
isTopMost() | boolean | Checks if modal is topmost |
1interface ModalOptions { 2 closeOnOutsideClick?: boolean; 3 closeOnEscape?: boolean; 4 customClass?: string; 5 hideCloseButton?: boolean; 6 backdrop?: 'static' | 'dynamic'; 7 keyboard?: boolean; 8 focus?: boolean; 9 size?: 'sm' | 'md' | 'lg' | 'xl'; 10 centered?: boolean; 11 scrollable?: boolean; 12 animation?: boolean; 13 animationDuration?: number; 14 closeOnRouteChange?: boolean; 15}
By default, modals will automatically close when the user navigates to a different route. This provides a better user experience and prevents modals from appearing in unexpected contexts.
1// Default behavior - modal closes on navigation 2<ngx-custom-modal #modal> 3 <!-- Modal content --> 4</ngx-custom-modal> 5 6// Explicitly enabled 7<ngx-custom-modal #modal [closeOnRouteChange]="true"> 8 <!-- Modal content --> 9</ngx-custom-modal>
For specific use cases where you want the modal to persist across route changes (shopping carts, media players, global notifications), you can disable this behavior:
1// Modal persists across route changes 2<ngx-custom-modal #modal [closeOnRouteChange]="false"> 3 <!-- Modal content --> 4</ngx-custom-modal> 5 6// Via options object 7modalOptions: ModalOptions = { 8 closeOnRouteChange: false, 9 // other options... 10};
If you're upgrading from a previous version and have modals that were designed to persist across routes, you'll need to explicitly set closeOnRouteChange: false
:
1// Before v20.0.0 (modals persisted by default) 2<ngx-custom-modal #modal> 3 <!-- Modal content --> 4</ngx-custom-modal> 5 6// After v20.0.0 (to maintain same behavior) 7<ngx-custom-modal #modal [closeOnRouteChange]="false"> 8 <!-- Modal content --> 9</ngx-custom-modal>
The library comes with modern CSS custom properties for easy theming:
1:root { 2 /* Modal backdrop */ 3 --modal-backdrop-bg: rgba(0, 0, 0, 0.5); 4 --modal-backdrop-blur: 2px; 5 6 /* Modal content */ 7 --modal-content-bg: #fff; 8 --modal-content-border: 1px solid rgba(0, 0, 0, 0.125); 9 --modal-content-border-radius: 0.5rem; 10 --modal-content-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); 11 12 /* Animations */ 13 --modal-animation-duration: 200ms; 14 --modal-z-index: 1050; 15} 16 17/* Basic modal styles */ 18.modal { 19 position: fixed; 20 top: 0; 21 left: 0; 22 width: 100%; 23 min-height: 100%; 24 background-color: var(--modal-backdrop-bg); 25 z-index: var(--modal-z-index); 26 display: flex; 27 align-items: center; 28 justify-content: center; 29 opacity: 0; 30 transition: opacity var(--modal-animation-duration) ease-in-out; 31 backdrop-filter: blur(var(--modal-backdrop-blur)); 32} 33 34.modal.in { 35 opacity: 1; 36} 37 38.modal-content { 39 background-color: var(--modal-content-bg); 40 border: var(--modal-content-border); 41 border-radius: var(--modal-content-border-radius); 42 box-shadow: var(--modal-content-shadow); 43 max-width: 500px; 44 width: 90%; 45} 46 47.modal-header { 48 display: flex; 49 justify-content: space-between; 50 align-items: center; 51 padding: 1rem; 52 border-bottom: 1px solid #dee2e6; 53} 54 55.modal-body { 56 padding: 1rem; 57} 58 59.modal-footer { 60 display: flex; 61 justify-content: flex-end; 62 gap: 0.5rem; 63 padding: 0.75rem; 64 border-top: 1px solid #dee2e6; 65} 66 67.close { 68 background: none; 69 border: none; 70 font-size: 1.5rem; 71 cursor: pointer; 72 padding: 0.25rem; 73 opacity: 0.5; 74 transition: opacity 0.15s ease-in-out; 75} 76 77.close:hover { 78 opacity: 0.75; 79}
For Bootstrap users, ngx-custom-modal works seamlessly with all Bootstrap versions:
1<!-- Bootstrap Modal Example --> 2<ngx-custom-modal #bootstrapModal [size]="'lg'" [centered]="true"> 3 <ng-template #modalHeader> 4 <h1 class="modal-title fs-5">Bootstrap Modal</h1> 5 </ng-template> 6 <ng-template #modalBody> 7 <div class="container-fluid"> 8 <div class="row"> 9 <div class="col-md-6"> 10 <p class="text-muted">Left column content</p> 11 </div> 12 <div class="col-md-6"> 13 <p class="text-muted">Right column content</p> 14 </div> 15 </div> 16 </div> 17 </ng-template> 18 <ng-template #modalFooter> 19 <button type="button" class="btn btn-secondary" (click)="bootstrapModal.close()">Close</button> 20 <button type="button" class="btn btn-primary">Save changes</button> 21 </ng-template> 22</ngx-custom-modal>
1/* Dark mode support */ 2@media (prefers-color-scheme: dark) { 3 :root { 4 --modal-backdrop-bg: rgba(0, 0, 0, 0.8); 5 --modal-content-bg: #1f2937; 6 --modal-content-border: 1px solid #374151; 7 --modal-text-color: #f9fafb; 8 } 9} 10 11/* Reduced motion support */ 12@media (prefers-reduced-motion: reduce) { 13 :root { 14 --modal-animation-duration: 0ms; 15 } 16} 17 18/* High contrast mode */ 19@media (prefers-contrast: high) { 20 :root { 21 --modal-content-border: 2px solid currentColor; 22 --modal-backdrop-bg: rgba(0, 0, 0, 0.9); 23 } 24}
1git clone https://github.com/AngelCareaga/ngx-custom-modal.git 2cd ngx-custom-modal 3npm install
1npm start
1npm run build:lib
1npm test
This project uses Prettier for code formatting:
1npm run format
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
git checkout -b feature/AmazingFeature
)git commit -m 'Add some AmazingFeature'
)git push origin feature/AmazingFeature
)This project is licensed under the MIT License - see the LICENSE file for details.
Made with ❤️ by Angel Careaga
⭐ Star this repo if you found it helpful!
No vulnerabilities found.
No security vulnerabilities found.