# brewdigital-modal

> A modal system for Angular

Latest version **0.1.4** (published 2019-03-19) · MIT license · 0 weekly downloads

## Install

```sh
npm install brewdigital-modal
pnpm add brewdigital-modal
yarn add brewdigital-modal
bun add brewdigital-modal
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities.

Warnings: low downloads; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.1.4 |
| Published | 2019-03-19 |
| First published | 2019-02-22 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 1 |
| Unpacked size | 199.2 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | brew-colin, brew-sean |

## Links

- npm: https://www.npmjs.com/package/brewdigital-modal
- Repository: https://bitbucket.org/brewdigital/brew-modal-lib/src/master/
- npm.io page: https://npm.io/package/brewdigital-modal

## Dependencies (1)

- [tslib](https://npm.io/package/tslib.md) ^1.9.0

## Recent versions

- 0.1.4 (latest) — 2019-03-19
- 0.1.3 — 2019-02-25
- 0.1.2 — 2019-02-23
- 0.1.1 — 2019-02-22
- 0.1.0 — 2019-02-22

## README

# Brew Modal Angular

A modal system for Angular

Install 

`npm install brewdigital-modal`  
or  
`yarn add brewdigital-modal`

## Components

The brewdigital-modal contains a couple of components that are read to use

- BrewMessageModalComponent 
- BrewConfirmModalComponent
- BrewMessageModalBootstrapComponent
- BrewConfirmModalBootstrapComponent

## Styling

The first two contain unstyled modals with some prefixed classes that can be used to style them.

```scss
.brew-modal-overlay {}
.brew-modal-holder {}
.brew-modal-header {}
.brew-modal-body {}
.brew-modal-footer {}
.brew-modal--padding {} 
.brew-modal--section-divider {}

// Container wrappers
.brew-modal--message {}
.brew-modal--confirm {}
```
The last two have Twitter Bootstrap styling applied. Use these if you are already using Bootstrap for styling.

## Usage

Start by adding `BrewModalModule` to a modules imports. 

For example it could be added to the AppModule

*app.module.ts*  
```typescript
import {NgModule} from '@angular/core';
import {AppComponent} from './app.component';
import {BrewModalModule} from 'brewdigital-modal';

@NgModule({
    declarations: [
        AppComponent,
    ],
    imports: [
        // ... Other imports
        BrewModalModule
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule {}
```


### BrewMessageComponent

Once the library has been included the components can be added to any component that uses the module.

*Message Component*
```html
<brew-message-modal>
    <p>This is a message.</p>
</brew-message-modal>
```

In order to access the methods on the component you need to add an Angular Template Reference Variable *eg* `#messageModal`

*Message Component with Tag*
```html
<brew-message-modal #messageModal>
    <p>This is a message.</p>
</brew-message-modal>
```

You can pick up a reference to your component with `ViewChild`.

Passing the reference `#messageModal` to 
`@ViewChild('messageModal') messageModalRef: BrewMessageModalComponent` 
gives you the variable `messageModalRef` that can access the `BrewMessageModalComponents` methods.

In this example we call the `this.messageModal.toggle()` method on `(click)="toggleMessageModal()"`.

```typescript
import {Component, ViewChild} from '@angular/core';
import {BrewMessageModalComponent} from 'brewdigital-modal';

@Component({
    selector: 'app-demo-message-modal',
    template: `
        <brew-message-modal #messageModal>
            <p>This is a message.</p>
        </brew-message-modal>
        <button (click)="toggleMessageModal()">Toggle Message Modal</button>
    `,
})
export class DemoMessageComponent {
    @ViewChild('messageModal') messageModalRef: BrewMessageModalComponent;

    toggleMessageModal() {
        this.messageModalRef.toggle();
    }
}
```

### BrewConfirmComponentModal

The `BrewConfirmComponentModal` has a `confirmActionResult` output. 

This is fired when the modals confirmation button is clicked and can be picked up with `(confirmActionResult)="handleConfirm($event)`.

*Confirm Component with Confirm Action*
```html
<brew-confirm-modal #confirmModal (confirmActionResult)="handleConfirm($event)">
    <p class="modal-text">Are you really, really sure?</p>
</brew-confirm-modal>
```

#### Actions

An `Action` can be passed to the modals `this.confirmModal.setConfirmAction()` method, its `execute` method is called when the confirm button is clicked. 

In the example below `ConfirmAction` is passed to the `setConfirmAction` on `ngAfterViewInit`.

The `ConfirmAction` returns true when it's `execute` method is called. 

Data can be passed to an actions `execute` method and can be handled however you like.

*Example Confirm Action*
```typescript
export class ConfirmAction implements Action {
    execute(data?: any): any {
        return true;
    }
}
```

*Passing Confirm Action to BrewConfirmModalComponent*
```typescript
ngAfterViewInit() {
    this.confirmModal.setConfirmAction(new ConfirmAction());
}
```

*Example Confirm Component*
```typescript
import {Component, ViewChild} from '@angular/core';
import {BrewConfirmModalComponent, ConfirmAction, CancelAction} from 'brewdigital-modal';

@Component({
    selector: 'app-confirm-demo',
    template: `
        <brew-confirm-modal 
            #confirmModal 
            (confirmActionResult)="handleAccepted($event)"
            (cancelActionResult)="handleAccepted($event)"
            >
            <p class="modal-text">Are you really, really sure?</p>
        </brew-confirm-modal>
        <button (click)="toggleConfirmModal()">Toggle Confirm Modal</button>
        <div *ngIf="accepted">
            <p>You're sure.</p>
        </div>
    `,
})
export class DemoConfirmComponent {

    @ViewChild('confirmModal') confirmModal: BrewConfirmModalComponent;

    accepted: boolean;

    ngAfterViewInit() {
        this.confirmModal.setConfirmAction(new ConfirmAction());
        this.confirmModal.setCancelAction(new CancelAction());
    }

    toggleConfirmModal() {
        this.accepted = false;
        this.confirmModal.toggle();
    }

    toggleFormModal() {
        this.message = '';
        this.modalForm.toggle();
    }
    
    handleAccepted(confirmed: boolean) {
        this.accepted = confirmed;
    }
}
```

## Actions

To handle events that occur inside a modal window classes that implement the `Action` interface can be passed to the modal. 
The `Action.execute()` method is then called to handle the event, the result should be exposed in an `@Output` in the modal. 
The `execute` method of an Action is called in the event emitter to expose the data to external components.

> ModalActionBase and ModalBase are two abstract classes that can be extended to create custom modals. 
> They provide useful methods for showing and hiding the modal and, accepting and cancelling events. 

*ModalActionBase*
```typescript
import {EventEmitter, Output} from '@angular/core';
import {ModalBase} from './modal-base';
import {Action} from '../../interface/action';

export abstract class ModalActionBase extends ModalBase {
    @Output() confirmActionResult = new EventEmitter();
    @Output() cancelActionResult = new EventEmitter();
    protected confirmAction: Action;
    protected cancelAction: Action;

    setConfirmAction(onConfirmCallback: Action) {
        this.confirmAction = onConfirmCallback;
    }

    setCancelAction(onCancelCallback: Action) {
        this.cancelAction = onCancelCallback;
    }

    confirmActionAndClose() {
        if (this.confirmAction) {
            this.confirmActionResult.emit(this.confirmAction.execute());
        }
        this.hideModal();
    }

    cancelActionAndClose() {
        if (this.cancelAction) {
            this.cancelActionResult.emit(this.cancelAction.execute());
        }
        this.hideModal();
    }
}
```

---
_Source: https://npm.io/package/brewdigital-modal · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
