{"id":15910549,"url":"https://github.com/kevcjones/ngx-simple-modal","last_synced_at":"2025-04-10T00:18:58.101Z","repository":{"id":45272395,"uuid":"112485615","full_name":"kevcjones/ngx-simple-modal","owner":"kevcjones","description":"A simple unopinionated framework to implement simple modal based behaviour in angular (v2+) projects.","archived":false,"fork":false,"pushed_at":"2024-01-18T23:24:05.000Z","size":12765,"stargazers_count":52,"open_issues_count":9,"forks_count":27,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-10-16T02:01:30.513Z","etag":null,"topics":["angular","component","dialog","modal","modal-components","ngx","reusable","typescript","ui"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kevcjones.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-11-29T14:29:47.000Z","updated_at":"2024-07-24T10:42:12.000Z","dependencies_parsed_at":"2024-06-18T15:32:08.047Z","dependency_job_id":"4513de6a-e48f-4aae-b4eb-1cd197c1a197","html_url":"https://github.com/kevcjones/ngx-simple-modal","commit_stats":null,"previous_names":[],"tags_count":58,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevcjones%2Fngx-simple-modal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevcjones%2Fngx-simple-modal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevcjones%2Fngx-simple-modal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevcjones%2Fngx-simple-modal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kevcjones","download_url":"https://codeload.github.com/kevcjones/ngx-simple-modal/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248131391,"owners_count":21052833,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","component","dialog","modal","modal-components","ngx","reusable","typescript","ui"],"created_at":"2024-10-06T15:08:31.224Z","updated_at":"2025-04-10T00:18:58.082Z","avatar_url":"https://github.com/kevcjones.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NGX Simple Modal [![Build Status](https://travis-ci.org/KevCJones/ngx-simple-modal.svg?branch=master)](https://travis-ci.org/KevCJones/ngx-simple-modal)\n\n## Features\n\nIt is a library to makes modals easier in Angular (2+), has no dependencies, but plays well with bootstrap or other frameworks.\n\n✅  Create clear and reusable modal components.    \n✅  It makes managing modals painless and clearer.   \n✅  Draggable modals  \n✅  Extend the ModalComponent class and implement any content you want.\n\n## Table of Contents\n\n- [Worked on](#worked-on)\n- [Demo](#demo)\n- [Installation](#installation)\n- [Quick start](#quickstart)\n- [How to create a draggable modal](#)\n- [Bootstrap](#what-if-i-want-to-use-bootstrap-3-or-4)\n\n## Worked on\n\n- Angular 9 with new ng-packagr updates supplied by the Angular tooling team themselves :bowtie:\n- Angular v8 also compatible with Angular Elements (December 2019)\n- Angular v4-7\n\n## Demo\n\nYou can see the demo in action here - [https://ngx-simple-modal-demo.stackblitz.io](https://ngx-simple-modal-demo.stackblitz.io)\nYou can have a play with this demo code here - [https://stackblitz.com/edit/ngx-simple-modal-demo?embed=1\u0026file=styles.css](https://stackblitz.com/edit/ngx-simple-modal-demo?embed=1\u0026file=styles.css)\n\nNG9 Preliminary test can be found here - [https://codesandbox.io/s/ngx-simple-modal-ng9-durdl](https://codesandbox.io/s/ngx-simple-modal-ng9-durdl)\n\nAnglar 11 demo can be found here - [https://stackblitz.com/edit/ngx-simple-modal-ng11-demo?file=src/app/app.component.html](https://stackblitz.com/edit/ngx-simple-modal-ng11-demo?file=src/app/app.component.html)\n\n## Installation\n```shell\n$ npm install ngx-simple-modal\n```\nor\n```shell\n$ yarn add ngx-simple-modal\n```\n\n## Quickstart\n\n### Step 0. assuming you want to use our built in styles\n\nTo create a custom modal box, you can start with the following example, wich is going to create a modal with a header, body and footer. The css already provide a transparency overlay, opacity and slide animation.\n\nInside your angular-cli.json update your styles sections to include our CSS\n```\n\"styles\": [\n  \"styles.css\",\n  \"../node_modules/ngx-simple-modal/styles/simple-modal.css\"\n],\n```\n\n#### But i use SASS/SCSS?\n\nWe got you covered, you can `@import '../node_modules/ngx-simple-modal/styles/simple-modal.scss'` into what ever root based scss global style you want. Update the relative path depending on where you want to pull it in.\n\n#### Assumed HTML template if you want our base styles\n\n```html\n\u003cdiv class=\"modal-content\"\u003e\n    \u003cdiv class=\"modal-header\"\u003e\n      \u003c!-- Your Title --\u003e\n    \u003c/div\u003e\n    \u003cdiv class=\"modal-body\"\u003e\n      \u003c!-- Modal custom content --\u003e\n    \u003c/div\u003e\n    \u003cdiv class=\"modal-footer\"\u003e\n      \u003c!--\n        Footer to add button control\n        ex.: \u003cbutton (click)=\"close()\"\u003eCancel\u003c/button\u003e\n      --\u003e\n    \u003c/div\u003e\n\u003c/div\u003e\n```\n\n\n### Step 1. Import the '**SimpleModalModule**' module\n\napp.module.ts:\n```typescript\nimport { NgModule} from '@angular/core';\nimport { CommonModule } from \"@angular/common\";\nimport { BrowserModule } from '@angular/platform-browser';\nimport { SimpleModalModule } from 'ngx-simple-modal';\nimport { AppComponent } from './app.component';\n@NgModule({\n  declarations: [\n    AppComponent\n  ],\n  imports: [\n    CommonModule,\n    BrowserModule,\n    SimpleModalModule\n  ],\n  bootstrap: [AppComponent]\n})\nexport class AppModule {}\n```\nBy default, modal placeholder will be added to AppComponent.\nBut you can select custom placeholder (i.e. document body):\n\n```typescript\nimports: [\n    ...\n    SimpleModalModule.forRoot({container:document.body})\n  ]\n```\n\nIf you want a container that is not yet in the DOM during the intial load you can pass a promiseLike function instead to container e.g.\n\n```typescript\nimports: [\n    ...\n    SimpleModalModule.forRoot({container: elementPromisingFn()})\n  ]\n```\n\nwhere `elementPromisingFn` is anything you want as long as its resolvement returns a nativeElement node from the DOM.\n\n#### Setting up modal defaults globally\n\nAn optional second parameter takes a global object of type SimpleModalOptions (all fields required).. you can spread\nthese with the defaultSimpleModalOptions if you like.\n\n```typescript\nimports: [\n    ...\n    SimpleModalModule.forRoot({container: 'modal-container'}, {...defaultSimpleModalOptions, ...{\n      closeOnEscape: true,\n      closeOnClickOutside: true,\n      wrapperDefaultClasses: 'modal fade-anim',\n      wrapperClass: 'in',\n      animationDuration: 400,\n      autoFocus: true\n    }})\n\n  ]\n```\n\nOR, if you need to control behaviour more granularly, you can provide the configuration in modules or locally like so\n\n```typescript\nprovide:[\n  {\n    provide: DefaultSimpleModalOptionConfig,\n    useValue: {...defaultSimpleModalOptions, ...{ closeOnEscape: true, closeOnClickOutside: true }}\n  }\n]\n```\n\n\n### Step 2. Create your modal component\nYour modal is expected to be extended from **SimpleModalComponent**.\n**SimpleModalService** is generic class with two arguments:\n1) input modal data type (data to initialize component);\n2) modal result type;\n\nTherefore **SimpleModalService** is supposed to be a constructor argument of **SimpleModalComponent**.\n\nconfirm.component.ts:\n```typescript\nimport { Component } from '@angular/core';\nimport { SimpleModalComponent } from \"ngx-simple-modal\";\nexport interface ConfirmModel {\n  title:string;\n  message:string;\n}\n@Component({\n    selector: 'confirm',\n    template: `\n      \u003cdiv class=\"modal-content\"\u003e\n        \u003cdiv class=\"modal-header\"\u003e\n          \u003ch4\u003e{{title || 'Confirm'}}\u003c/h4\u003e\n        \u003c/div\u003e\n        \u003cdiv class=\"modal-body\"\u003e\n          \u003cp\u003e{{message || 'Are you sure?'}}\u003c/p\u003e\n        \u003c/div\u003e\n        \u003cdiv class=\"modal-footer\"\u003e\n          \u003cbutton type=\"button\" class=\"btn btn-outline-danger\" (click)=\"close()\" \u003eCancel\u003c/button\u003e\n          \u003cbutton type=\"button\" class=\"btn btn-primary\" (click)=\"confirm()\"\u003eOK\u003c/button\u003e\n        \u003c/div\u003e\n      \u003c/div\u003e\n    `\n})\nexport class ConfirmComponent extends SimpleModalComponent\u003cConfirmModel, boolean\u003e implements ConfirmModel {\n  title: string;\n  message: string;\n  constructor() {\n    super();\n  }\n  confirm() {\n    // we set modal result as true on click on confirm button,\n    // then we can get modal result from caller code\n    this.result = true;\n    this.close();\n  }\n}\n```\n\n### Step 3. Register created component to module\nAdd component to **declarations** and **entryComponents** section, because the component\nwill be created dynamically.\n\napp.module.ts:\n```typescript\n    import { NgModule} from '@angular/core';\n    import { CommonModule } from \"@angular/common\";\n    import { BrowserModule } from '@angular/platform-browser';\n    import { SimpleModalModule } from 'ngx-simple-modal';\n    import { ConfirmComponent } from './confirm.component';\n    import { AppComponent } from './app.component';\n    @NgModule({\n      declarations: [\n        AppComponent,\n        ConfirmComponent\n      ],\n      imports: [\n        CommonModule,\n        BrowserModule,\n        SimpleModalModule\n      ],\n      //Don't forget to add the component to entryComponents section\n      entryComponents: [\n        ConfirmComponent\n      ],\n      bootstrap: [AppComponent]\n    })\n    export class AppModule {}\n```\n\n### Step 4. Usage\n\napp.component.ts\n```typescript\n    import { Component } from '@angular/core';\n    import { ConfirmComponent } from './confirm.component';\n    import { SimpleModalService } from \"ngx-simple-modal\";\n\n    @Component({\n      selector: 'app',\n      template: `\n        \u003cdiv class=\"modal-content\"\u003e\n          \u003cdiv class=\"modal-header\"\u003e\n            \u003ch4\u003eConfirm\u003c/h4\u003e\n          \u003c/div\u003e\n          \u003cdiv class=\"modal-body\"\u003e\n            \u003cp\u003eAre you sure?\u003c/p\u003e\n          \u003c/div\u003e\n          \u003cdiv class=\"modal-footer\"\u003e\n            \u003cbutton type=\"button\" class=\"btn btn-primary\" (click)=\"showConfirm()\"\u003eShow confirm\u003c/button\u003e\n          \u003c/div\u003e\n        \u003c/div\u003e\n      `\n    })\n    export class AppComponent {\n        constructor(private simpleModalService:SimpleModalService) {}\n        showConfirm() {\n            let disposable = this.simpleModalService.addModal(ConfirmComponent, {\n                  title: 'Confirm title',\n                  message: 'Confirm message'\n                })\n                .subscribe((isConfirmed)=\u003e{\n                    //We get modal result\n                    if(isConfirmed) {\n                        alert('accepted');\n                    }\n                    else {\n                        alert('declined');\n                    }\n                });\n            //We can close modal calling disposable.unsubscribe();\n            //If modal was not closed manually close it by timeout\n            setTimeout(()=\u003e{\n                disposable.unsubscribe();\n            },10000);\n        }\n    }\n```\n\n## How to create a draggable modal\n\nSo you want to be able to move the modal around. We got that too. It is as simple as adding `draggable: true` to the options. This will default to adding a drag handler to the entire modal. With this you can move the modal around.\n\n```typescript\nimports: [\n  SimpleModalModule.forRoot({...}, {\n      ...\n      draggable: true\n      ...\n    })\n],\n```\nor when adding the modal\n```typescript\nthis.simpleModalService\n  .addModal(PromptComponent, {\n    title: 'Name dialog',\n  }, {\n    draggable: true\n  })\n```\n\nThe `draggable` class with automatically be attached to the modal component. The class can be customized through the `draggableClass` option property.\n\n### Custom drag handler\nYou can specify which element should be used as drag handler by using `ViewChild` and naming the property `handle`.\n```typescript\n@ViewChild('handle', {static: true}) handle: ElementRef;\n```\nThen in your view add `#handle` to the element you want to use as the drag handler. The `drag-handler` class will automatically be attached to this element.\n\n```angular2html\n\u003cdiv class=\"modal-content\"\u003e\n  \u003cdiv class=\"modal-header\" #handle\u003e\n    \u003ch4\u003eTitle\u003c/h4\u003e\n  \u003c/div\u003e\n  \u003cdiv class=\"modal-body\"\u003e\n    Bla bla bla\n  \u003c/div\u003e\n  \u003cdiv class=\"modal-footer\"\u003e\n    Footer modal\n  \u003c/div\u003e\n\u003c/div\u003e\n```\n\n## What if i want to use Bootstrap 3 or 4?\n\nWe got you! An example boostrap alert modal component.\n\n```typescript\nimport { Component } from '@angular/core';\nimport { SimpleModalComponent } from 'ngx-simple-modal';\n\nexport interface AlertModel {\n  title: string;\n  message: string;\n}\n\n@Component({\n  selector: 'alert',\n  template: `\u003cdiv class=\"modal-dialog\"\u003e\n                \u003cdiv class=\"modal-content\"\u003e\n                   \u003cdiv class=\"modal-header\"\u003e\n                     \u003cbutton type=\"button\" class=\"close\" (click)=\"close()\" \u003e\u0026times;\u003c/button\u003e\n                     \u003ch4 class=\"modal-title\"\u003e{{title || 'Alert!'}}\u003c/h4\u003e\n                   \u003c/div\u003e\n                   \u003cdiv class=\"modal-body\"\u003e\n                     \u003cp\u003e{{message || 'TADAA-AM!'}}\u003c/p\u003e\n                   \u003c/div\u003e\n                   \u003cdiv class=\"modal-footer\"\u003e\n                     \u003cbutton type=\"button\" class=\"btn btn-primary\" (click)=\"close()\"\u003eOK\u003c/button\u003e\n                   \u003c/div\u003e\n                \u003c/div\u003e\n             \u003c/div\u003e`\n})\nexport class AlertComponent extends SimpleModalComponent\u003cAlertModel, null\u003e implements AlertModel {\n  title: string;\n  message: string;\n  constructor() {\n    super();\n  }\n}\n```\n\nAs you can see, the implementation is completely in your control. We're just here to help you create, configure, add, track inputs, and remove.\n\n## Documentation\n\n### SimpleModalComponent\nSuper class of all modal components.\n#### Class Overview\n```typescript\n/**\n* Dialog abstract class\n* @template T1 - input modal data\n* @template T2 - modal result\n*/\nabstract abstract class SimpleModalComponent\u003cT1, T2\u003e implements T1, OnDestroy {\n    /**\n    * Constructor\n    * @param {SimpleModalService} simpleModalService - instance of SimpleModalService\n    */\n    constructor(simpleModalService: SimpleModalService)\n\n    /**\n    * Dialog result\n    * @type {T2}\n    */\n    protected result:T2\n\n    /**\n    * Closes modal\n    */\n    public close:Function\n\n    /**\n    * OnDestroy handler\n    * Sends modal result to observer\n    */\n    public ngOnDestroy:Function\n}\n```\n\n### SimpleModalOptions\n```typescript\ninterface SimpleModalOptions {\n\n  /**\n  * clicking outside your content will be close the modal.\n  * @default false\n  * @type {boolean}\n  */\n  closeOnClickOutside?: boolean;\n\n  /**\n  * Flag to close modal by click on backdrop (outside modal)\n  * @default false\n  * @type {boolean}\n  */\n  closeOnEscape: boolean;\n\n  /**\n  * Class to put in document body while modal is open\n  * @default 'modal-open'\n  * @type {string}\n  */\n  bodyClass: string;\n\n\n  /**\n  * Default classes which live in modal wrapper. Change if you need to for your own css requirements\n  * @default 'modal fade'\n  * @type {string}\n  */\n  wrapperDefaultClasses: string,\n\n  /**\n  * Class we add and remove from modal when we add it/ remove it\n  * @default 'in'\n  * @type {string}\n  */\n  wrapperClass: string,\n  /**\n  * Time we wait while adding and removing to let animation play\n  * @type {string}\n  * @default 300\n  */\n  animationDuration: number;\n\n  /**\n  * FInds teh first focusable element in the page and applies focus on open  after closing restores focus back to previous\n  * @type {boolean}\n  * @default false\n  */\n  autoFocus: number;\n}\n```\n\n### SimpleModalService\nService to show and hide modals\n\n### Class Overview\n```typescript\nclass SimpleModalService {\n    /**\n    * Adds modal\n    * @param {Type\u003cSimpleModalComponent\u003cT1, T2\u003e} component - modal component\n    * @param {T1?} data - Initialization data for component (optional) to add to component instance and can be used in component code or template\n    * @param {SimpleModalOptions?} Dialog options\n    * @return {Observable\u003cT2\u003e} - returns Observable to get modal result\n    */\n    public addModal\u003cT1, T2\u003e(component:Type\u003cSimpleModalComponent\u003cT1, T2\u003e\u003e, data?:T1, options: SimpleModalOptions): Observable\u003cT2\u003e =\u003e {}\n\n    /**\n     * Remove a modal externally\n     * @param [SimpleModalComponent} component\n     */\n    public removeModal(component: SimpleModalComponent\u003cany, any\u003e): void;\n\n    /**\n     * Removes all open modals in one go\n     */\n    public removeAll(): void {\n\n}\n```\n\n## Credits\n\nThis project was seeded by [https://github.com/ankosoftware/ng2-bootstrap-modal](https://github.com/ankosoftware/ng2-bootstrap-modal) because the author was not responding to pull requests so decided to take what they had started and update and run with it. Along the way we put some of our own opinions on it and added some tests, enough changes that it stopped being a viable PR for the original without serious breaking changes.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevcjones%2Fngx-simple-modal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkevcjones%2Fngx-simple-modal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevcjones%2Fngx-simple-modal/lists"}