<!DOCTYPE html>
<html>

  <head>
    <title>angular2 playground</title>
    <link rel="stylesheet" href="style.css" />
    <!-- Place this tag in your head or just before your close body tag. -->
    <script src="https://code.angularjs.org/2.0.0-beta.17/angular2-polyfills.js"></script>
    <script src="https://code.angularjs.org/tools/system.js"></script>
    <script src="https://code.angularjs.org/tools/typescript.js"></script>
    <script src="config.js"></script>
    <script>
    System.import('app')
      .catch(console.error.bind(console));
  </script>
  </head>

  <body>
    <my-app>
      loading...
    </my-app>
  </body>

</html>
/* Styles go here */

@import "https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/css/materialize.min.css";
@import "https://fonts.googleapis.com/icon?family=Material+Icons";

body {
  margin-top: 30px;
}

form {
  margin-top: 20px;
}

body {
  background: rgba(0,0,0,0.02);
}
### Angular2 Starter Plunker - Typescript - RC.0

A simple plunker demonstrating Angular2 usage:
- Uses SystemJS + TypeScript to compile on the fly
- Includes binding, directives, http, pipes, and DI usage.
System.config({
  //use typescript for compilation
  transpiler: 'typescript',
  //typescript compiler options
  typescriptOptions: {
    emitDecoratorMetadata: true
  },
  //map tells the System loader where to look for things
  map: {
    app: "./src",
    '@angular': 'https://npmcdn.com/@angular',
    'rxjs': 'https://npmcdn.com/rxjs@5.0.0-beta.6'
  },
  //packages defines our app package
  packages: {
    app: {
      main: './main.ts',
      defaultExtension: 'ts'
    },
    '@angular/core': {
      main: 'core.umd.js',
      defaultExtension: 'js'
    },
    '@angular/compiler': {
      main: 'compiler.umd.js',
      defaultExtension: 'js'
    },
    '@angular/common': {
      main: 'common.umd.js',
      defaultExtension: 'js'
    },
    '@angular/platform-browser-dynamic': {
      main: 'platform-browser-dynamic.umd.js',
      defaultExtension: 'js'
    },
    '@angular/platform-browser': {
      main: 'platform-browser.umd.js',
      defaultExtension: 'js'
    },
    rxjs: {
      defaultExtension: 'js'
    }
  }
});
//main entry point
import {bootstrap} from '@angular/platform-browser-dynamic';
import {App} from './app';

bootstrap(App, [])
  .catch(err => console.error(err));
//our root app component
import {Component} from '@angular/core'
import {PushNotificationComponent} from './ng2-notifications';

@Component({
  selector: 'my-app',
  providers: [],
  template: `
    <main class="container">
      
      <push-notification #myNotification
        [title]="notification.title"
        [body]="notification.body"
        [icon]="notification.icon"
        [closeDelay]="notification.closeDelay"
        (action)="notification.action($event)">
      </push-notification>
      
      <article class="row">
        <header class="col s12">
          <h5>
            <i class="left material-icons">add_alert</i> 
            <span>ng2-notifications</span>
          </h5>
        </header>
        <form (submit)="myNotification.show()" class="col s12">
          <div class="row">
            <div class="input-field col s6">
              <input type="text" id="title" [(ngModel)]="notification.title" class="validate" required />
              <label class="active" for="title">Title</label>
            </div>
            <div class="input-field col s6">
              <input type="text" id="body" [(ngModel)]="notification.body" class="validate" required />
              <label class="active" for="body">Body</label>
            </div>
          </div>
          <div class="row">
            <div class="input-field col s6">
              <input type="text" id="icon" [(ngModel)]="notification.icon" class="validate" />
              <label class="active" for="icon">Icon</label>
            </div>
            <div class="input-field col s6">
              <input type="text" id="closeDelay" placeholder="Milliseconds" [(ngModel)]="notification.closeDelay" class="validate" />
              <label class="active" for="closeDelay">Close Delay</label>
            </div>
          </div>
          <div class="row">
            <div class="col s12">
              <button type="submit" class="btn red darken-2 waves-effect waves-light">Show Notification</button>
            </div>
          </div>
        </form>
      </article>
      
    </main>
  `,
  directives: [PushNotificationComponent]
})

export class App {
  
  public notification: any = {
    show: false,
    title: 'New Angular 2 Library!',
    body: 'ng2-notifications',
    icon: 'https://goo.gl/3eqeiE',
    action: function () {
      window.open('https://github.com/alexcastillo/ng2-notifications');
    }
  };
  
}
import {
  Component,
  EventEmitter,
  OnInit,
  OnChanges,
  OnDestroy,
  Input,
  Output
} from '@angular/core';

declare var Notification;

@Component({
  selector: 'push-notification',
  styles: [':host { display: none; }'],
  template: ''
})

export class PushNotificationComponent implements OnInit, OnChanges, OnDestroy {

  @Input() public title: string;
  @Input() public body: string;
  @Input() public icon: string;
  @Input() public sound: string;
  @Input() public data: any;
  @Input() public tag: string;
  @Input() public dir: string = 'auto';
  @Input() public lang: string = 'en-US';
  @Input() public renotify: boolean = false;
  @Input() public sticky: boolean = false;
  @Input() public vibrate: Array<number>;
  @Input() public noscreen: boolean = false;
  @Input() public silent: boolean = true;
  @Input() public closeDelay: number = 0;

  @Output('load') public onLoad: EventEmitter<any> = new EventEmitter();
  @Output('show') public onShow: EventEmitter<any> = new EventEmitter();
  @Output('close') public onClose: EventEmitter<any> = new EventEmitter();
  @Output('error') public onError: EventEmitter<any> = new EventEmitter();
  @Output('action') public onClick: EventEmitter<any> = new EventEmitter();

  public checkCompatibility () {
    return !!('Notification' in window);
  }

  public isPermissionGranted (permission) {
    return permission === 'granted';
  }

  public requestPermission () {
    return Notification.requestPermission();
  }

  public show () {
    if (!this.checkCompatibility()) {
        return console.log('Notification API not available in this browser.');
    }

    return this.requestPermission()
      .then((permission) => this.isPermissionGranted(permission))
      .then(() => this.create());
  }

  public create () {
    let notification = new Notification(this.title, {
      dir: this.dir,
      lang: this.lang,
      data: this.data,
      tag: this.tag,
      body: this.body,
      icon: this.icon,
      silent: this.silent,
      sound: this.sound,
      renotify: this.renotify,
      sticky: this.sticky,
      vibrate: this.vibrate,
      noscreen: this.noscreen
    });

    this.attachEventHandlers(notification);
    this.close(notification);

    return notification;
  }

  public close (notification): void {
    if (this.closeDelay) {
      setTimeout(() => {
        notification.close();
      }, this.closeDelay);
    } else {
      notification.close();
    }
  }

  public closeAll (): void {
    Notification.close();
  }

  attachEventHandlers (notification): void {
    notification.onshow = () => {
      this.onShow.emit({ notification });
    };

    notification.onclick = (event) => {
      this.onClick.emit({ event, notification });
    };

    notification.onerror = () => {
      this.onError.emit({ notification });
    };

    notification.onclose = () => {
      this.onClose.emit({ notification });
    };
  }

  public ngOnInit (): void {
    this.onLoad.emit({});
  }

  public ngOnDestroy (): void {
    this.closeAll();
  }

  public ngOnChanges(): void {
  }

}