├── .editorconfig
├── .github
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── LICENSE
├── README.md
├── angular-cli.json
├── e2e
├── app.e2e-spec.ts
├── app.po.ts
└── tsconfig.json
├── karma.conf.js
├── package.json
├── protractor.conf.js
├── src
├── app
│ ├── app.component.css
│ ├── app.component.html
│ ├── app.component.spec.ts
│ ├── app.component.ts
│ ├── app.module.ts
│ ├── app.routing.ts
│ ├── dnd
│ │ ├── custom-data-dnd.component.ts
│ │ ├── custom-function-dnd.component.ts
│ │ ├── demo-dnd.module.ts
│ │ ├── dnd.component.html
│ │ ├── dnd.component.ts
│ │ ├── embedded-sortable.component.ts
│ │ ├── multi-sortable.component.ts
│ │ ├── recycle-multi-sortable.component.ts
│ │ ├── shopping-basket-dnd.component.ts
│ │ ├── simple-dnd.component.ts
│ │ ├── simple-sortable-copy.component.ts
│ │ ├── simple-sortable.component.ts
│ │ └── zone-dnd.component.ts
│ ├── home
│ │ ├── home.component.html
│ │ └── home.component.ts
│ ├── index.ts
│ ├── slim
│ │ ├── slim.component.html
│ │ └── slim.component.ts
│ └── toast
│ │ ├── index.ts
│ │ ├── toast-communication.service.ts
│ │ └── toast.component.ts
├── assets
│ ├── .gitkeep
│ └── .npmignore
├── environments
│ ├── environment.prod.ts
│ └── environment.ts
├── favicon.ico
├── index.html
├── main.ts
├── polyfills.ts
├── skeleton.css
├── styles.css
├── test.ts
├── tsconfig.json
└── typings.d.ts
└── tslint.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | max_line_length = off
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Read and contribute to the Wiki
2 |
3 | Make sure you read the Wiki
4 | https://github.com/akserg/ng2-webpack-demo/wiki
5 |
6 | ## Submitting Pull Requests
7 | If you're changing the structure of the repository please create an issue first
8 |
9 | ## Submitting bug reports
10 |
11 | Make sure you are on latest changes and that you ran this command `npm run clean:install` after updating your local repository. If you can, please provide more infomation about your environment such as browser, operating system, node version, and npm version
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | * **I'm submitting a ...**
2 | [ ] bug report
3 | [ ] feature request
4 | [ ] question about the decisions made in the repository
5 |
6 | * **Do you want to request a *feature* or report a *bug*?**
7 |
8 |
9 |
10 | * **What is the current behavior?**
11 |
12 |
13 |
14 | * **If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem** via https://plnkr.co or similar.
15 |
16 |
17 |
18 | * **What is the expected behavior?**
19 |
20 |
21 |
22 | * **What is the motivation / use case for changing the behavior?**
23 |
24 |
25 |
26 | * **Please tell us about your environment:**
27 |
28 | - Angular version: 2.0.0-beta.X
29 | - Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
30 |
31 |
32 |
33 | * **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc)
34 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | * **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...)
2 |
3 |
4 |
5 | * **What is the current behavior?** (You can also link to an open issue here)
6 |
7 |
8 |
9 | * **What is the new behavior (if this is a feature change)?**
10 |
11 |
12 |
13 | * **Other information**:
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 |
7 | # dependencies
8 | /node_modules
9 |
10 | # IDEs and editors
11 | /.idea
12 | .project
13 | .classpath
14 | .c9/
15 | *.launch
16 | .settings/
17 |
18 | # IDE - VSCode
19 | .vscode/*
20 | !.vscode/settings.json
21 | !.vscode/tasks.json
22 | !.vscode/launch.json
23 | !.vscode/extensions.json
24 |
25 | # misc
26 | /.sass-cache
27 | /connect.lock
28 | /coverage/*
29 | /libpeerconnection.log
30 | npm-debug.log
31 | testem.log
32 | /typings
33 |
34 | # e2e
35 | /e2e/*.js
36 | /e2e/*.map
37 |
38 | #System Files
39 | .DS_Store
40 | Thumbs.db
41 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015-2016 AngularClass LLC
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ng2-webpack-demo
2 |
3 | This project was generated with [angular-cli](https://github.com/angular/angular-cli) version 1.0.0-beta.24.
4 | It demonstrates the use of different libraries such:
5 | > - [ng2-dnd](https://github.com/akserg/ng2-dnd): Angular 2 Drag-and-Drop without dependencies
6 | > - [ng2-toasty](https://github.com/akserg/ng2-toasty): Angular2 Toasty component shows growl-style alerts and messages for your application
7 | > - [ng2-slim-loading-bar](https://github.com/akserg/ng2-slim-loading-bar): Angular 2 component shows slim loading bar at the top of the page
8 |
9 | Online demo available [here](http://akserg.github.io/ng2-webpack-demo)
10 |
11 |
12 | ## Development server
13 | Run `npm start` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
14 |
15 | ## Code scaffolding
16 |
17 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/class/module`.
18 |
19 | ## Build
20 |
21 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
22 |
23 | ## Build with AOT
24 |
25 | Run `npm run aot:buildd` to build the project for production with Ahead of Time (AOT) compilation. The build artifacts will be stored in the `dist/` directory.
26 | Use the `npm run aot:start` to start server in production with AOT.
27 |
28 | ## Running unit tests
29 |
30 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
31 |
32 | ## Running end-to-end tests
33 |
34 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
35 | Before running the tests make sure you are serving the app via `ng serve`.
36 |
37 | ## Deploying to Github Pages
38 |
39 | Run `ng github-pages:deploy` to deploy to Github Pages.
40 |
41 | ## Further help
42 | To get more help on the `angular-cli` use `ng help` or go check out the [Angular-CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
43 |
44 | # License
45 | [MIT](/LICENSE)
--------------------------------------------------------------------------------
/angular-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "project": {
3 | "version": "1.0.0-beta.24",
4 | "name": "ng2-webpack-demo"
5 | },
6 | "apps": [
7 | {
8 | "root": "src",
9 | "outDir": "dist",
10 | "assets": [
11 | "assets",
12 | "favicon.ico"
13 | ],
14 | "index": "index.html",
15 | "main": "main.ts",
16 | "test": "test.ts",
17 | "tsconfig": "tsconfig.json",
18 | "prefix": "app",
19 | "mobile": false,
20 | "styles": [
21 | "../node_modules/ng2-toasty/style.css",
22 | "../node_modules/ng2-dnd/style.css",
23 | "../node_modules/ng2-slim-loading-bar/style.css",
24 | "skeleton.css",
25 | "styles.css"
26 | ],
27 | "scripts": [],
28 | "environmentSource": "environments/environment.ts",
29 | "environments": {
30 | "dev": "environments/environment.ts",
31 | "prod": "environments/environment.prod.ts"
32 | }
33 | }
34 | ],
35 | "addons": [],
36 | "packages": [],
37 | "e2e": {
38 | "protractor": {
39 | "config": "./protractor.conf.js"
40 | }
41 | },
42 | "test": {
43 | "karma": {
44 | "config": "./karma.conf.js"
45 | }
46 | },
47 | "defaults": {
48 | "styleExt": "css",
49 | "prefixInterfaces": false,
50 | "inline": {
51 | "style": false,
52 | "template": false
53 | },
54 | "spec": {
55 | "class": false,
56 | "component": true,
57 | "directive": true,
58 | "module": false,
59 | "pipe": true,
60 | "service": true
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/e2e/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { Ng2WebpackDemoPage } from './app.po';
2 |
3 | describe('ng2-webpack-demo App', function() {
4 | let page: Ng2WebpackDemoPage;
5 |
6 | beforeEach(() => {
7 | page = new Ng2WebpackDemoPage();
8 | });
9 |
10 | it('should display message saying app works', () => {
11 | page.navigateTo();
12 | expect(page.getParagraphText()).toEqual('app works!');
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/e2e/app.po.ts:
--------------------------------------------------------------------------------
1 | import { browser, element, by } from 'protractor';
2 |
3 | export class Ng2WebpackDemoPage {
4 | navigateTo() {
5 | return browser.get('/');
6 | }
7 |
8 | getParagraphText() {
9 | return element(by.css('app-root h1')).getText();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "declaration": false,
5 | "emitDecoratorMetadata": true,
6 | "experimentalDecorators": true,
7 | "module": "commonjs",
8 | "moduleResolution": "node",
9 | "outDir": "../dist/out-tsc-e2e",
10 | "sourceMap": true,
11 | "target": "es5",
12 | "typeRoots": [
13 | "../node_modules/@types"
14 | ]
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/0.13/config/configuration-file.html
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | basePath: '',
7 | frameworks: ['jasmine', 'angular-cli'],
8 | plugins: [
9 | require('karma-jasmine'),
10 | require('karma-chrome-launcher'),
11 | require('karma-remap-istanbul'),
12 | require('angular-cli/plugins/karma')
13 | ],
14 | files: [
15 | { pattern: './src/test.ts', watched: false }
16 | ],
17 | preprocessors: {
18 | './src/test.ts': ['angular-cli']
19 | },
20 | mime: {
21 | 'text/x-typescript': ['ts','tsx']
22 | },
23 | remapIstanbulReporter: {
24 | reports: {
25 | html: 'coverage',
26 | lcovonly: './coverage/coverage.lcov'
27 | }
28 | },
29 | angularCli: {
30 | config: './angular-cli.json',
31 | environment: 'dev'
32 | },
33 | reporters: config.angularCli && config.angularCli.codeCoverage
34 | ? ['progress', 'karma-remap-istanbul']
35 | : ['progress'],
36 | port: 9876,
37 | colors: true,
38 | logLevel: config.LOG_INFO,
39 | autoWatch: true,
40 | browsers: ['Chrome'],
41 | singleRun: false
42 | });
43 | };
44 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ng2-webpack-demo",
3 | "version": "0.0.0",
4 | "license": "MIT",
5 | "angular-cli": {},
6 | "scripts": {
7 | "ng": "ng",
8 | "start": "ng serve",
9 | "lint": "tslint \"src/**/*.ts\"",
10 | "test": "ng test",
11 | "pree2e": "webdriver-manager update --standalone false --gecko false",
12 | "e2e": "protractor",
13 | "aot:build": "ng build --prod --aot",
14 | "aot:start": "ng serve --prod --aot"
15 | },
16 | "private": true,
17 | "dependencies": {
18 | "@angular/common": "^2.4.7",
19 | "@angular/compiler": "^2.4.7",
20 | "@angular/core": "^2.4.7",
21 | "@angular/forms": "^2.4.7",
22 | "@angular/http": "^2.4.7",
23 | "@angular/platform-browser": "^2.4.7",
24 | "@angular/platform-browser-dynamic": "^2.4.7",
25 | "@angular/router": "^3.4.7",
26 | "core-js": "^2.4.1",
27 | "rxjs": "^5.1.1",
28 | "ts-helpers": "^1.1.1",
29 | "zone.js": "^0.7.7",
30 | "ng2-dnd": "^2.2.2",
31 | "ng2-slim-loading-bar": "^2.3.0",
32 | "ng2-toasty": "^2.4.0"
33 | },
34 | "devDependencies": {
35 | "@angular/cli": "1.0.0-beta.32.3",
36 | "@angular/compiler-cli": "^2.4.7",
37 | "@types/jasmine": "2.5.43",
38 | "@types/node": "^7.0.5",
39 | "codelyzer": "~2.0.0-beta.2",
40 | "jasmine-core": "2.5.2",
41 | "jasmine-spec-reporter": "3.2.0",
42 | "karma": "1.4.0",
43 | "karma-chrome-launcher": "^2.0.0",
44 | "karma-cli": "^1.0.1",
45 | "karma-jasmine": "^1.0.2",
46 | "karma-remap-istanbul": "^0.6.0",
47 | "protractor": "~5.1.1",
48 | "ts-node": "2.1.0",
49 | "tslint": "4.3.1",
50 | "typescript": "~2.1.6"
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/protractor.conf.js:
--------------------------------------------------------------------------------
1 | // Protractor configuration file, see link for more information
2 | // https://github.com/angular/protractor/blob/master/lib/config.ts
3 |
4 | /*global jasmine */
5 | var SpecReporter = require('jasmine-spec-reporter');
6 |
7 | exports.config = {
8 | allScriptsTimeout: 11000,
9 | specs: [
10 | './e2e/**/*.e2e-spec.ts'
11 | ],
12 | capabilities: {
13 | 'browserName': 'chrome'
14 | },
15 | directConnect: true,
16 | baseUrl: 'http://localhost:4200/',
17 | framework: 'jasmine',
18 | jasmineNodeOpts: {
19 | showColors: true,
20 | defaultTimeoutInterval: 30000,
21 | print: function() {}
22 | },
23 | useAllAngular2AppRoots: true,
24 | beforeLaunch: function() {
25 | require('ts-node').register({
26 | project: 'e2e'
27 | });
28 | },
29 | onPrepare: function() {
30 | jasmine.getEnv().addReporter(new SpecReporter());
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/src/app/app.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akserg/ng2-webpack-demo/8e524bc87a41dae716a288306d76afda610fe1e7/src/app/app.component.css
--------------------------------------------------------------------------------
/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | /* tslint:disable:no-unused-variable */
2 |
3 | import { TestBed, async } from '@angular/core/testing';
4 | import { AppComponent } from './app.component';
5 |
6 | describe('AppComponent', () => {
7 | beforeEach(() => {
8 | TestBed.configureTestingModule({
9 | declarations: [
10 | AppComponent
11 | ],
12 | });
13 | TestBed.compileComponents();
14 | });
15 |
16 | it('should create the app', async(() => {
17 | let fixture = TestBed.createComponent(AppComponent);
18 | let app = fixture.debugElement.componentInstance;
19 | expect(app).toBeTruthy();
20 | }));
21 |
22 | it(`should have as title 'app works!'`, async(() => {
23 | let fixture = TestBed.createComponent(AppComponent);
24 | let app = fixture.debugElement.componentInstance;
25 | expect(app.title).toEqual('app works!');
26 | }));
27 |
28 | it('should render title in a h1 tag', async(() => {
29 | let fixture = TestBed.createComponent(AppComponent);
30 | fixture.detectChanges();
31 | let compiled = fixture.debugElement.nativeElement;
32 | expect(compiled.querySelector('h1').textContent).toContain('app works!');
33 | }));
34 | });
35 |
--------------------------------------------------------------------------------
/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2016 Sergey Akopkokhyants
2 | // This project is licensed under the terms of the MIT license.
3 | // https://github.com/akserg
4 |
5 | import { Component, OnDestroy } from '@angular/core';
6 | import { Router, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from '@angular/router';
7 |
8 | import { SlimLoadingBarService } from 'ng2-slim-loading-bar';
9 |
10 | import { ToastCommunicationService } from './toast/toast-communication.service';
11 |
12 | @Component({
13 | selector: 'app-root',
14 | templateUrl: './app.component.html'
15 | })
16 | export class AppComponent implements OnDestroy {
17 | private sub: any;
18 | // Position of Ng2ToastyComponent
19 | private toastyComponentPosition: string;
20 |
21 | constructor(private slimLoader: SlimLoadingBarService, private router: Router,
22 | private toastCommunicationService: ToastCommunicationService) {
23 | // We listen the position's changes
24 | this.toastCommunicationService.position$.subscribe(pos => this.toastyComponentPosition = pos);
25 | // Listen the navigation events to start or complete the slim bar loading
26 | this.sub = this.router.events.subscribe(event => {
27 | if (event instanceof NavigationStart) {
28 | this.slimLoader.start();
29 | } else if ( event instanceof NavigationEnd ||
30 | event instanceof NavigationCancel ||
31 | event instanceof NavigationError) {
32 | this.slimLoader.complete();
33 | }
34 | }, (error: any) => {
35 | this.slimLoader.complete();
36 | });
37 | }
38 |
39 | ngOnDestroy(): any {
40 | this.sub.unsubscribe();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2016 Sergey Akopkokhyants
2 | // This project is licensed under the terms of the MIT license.
3 | // https://github.com/akserg
4 |
5 | import { NgModule } from '@angular/core';
6 | import { BrowserModule } from '@angular/platform-browser';
7 | import { FormsModule } from '@angular/forms';
8 | import { LocationStrategy, HashLocationStrategy } from '@angular/common';
9 |
10 | import { AppComponent } from './app.component';
11 |
12 | import { ToastyModule } from 'ng2-toasty';
13 | import { DndModule } from 'ng2-dnd';
14 | import { SlimLoadingBarModule } from 'ng2-slim-loading-bar';
15 | import { DemoDndModule } from './dnd/demo-dnd.module';
16 |
17 | import { HomeComponent } from './home/home.component';
18 | import { SlimComponent } from './slim/slim.component';
19 | import { DndComponent } from './dnd/dnd.component';
20 | import { ToastComponent, ToastCommunicationService } from './toast';
21 |
22 | import { routing } from './app.routing';
23 |
24 | @NgModule({
25 | imports: [BrowserModule, FormsModule, routing,
26 | ToastyModule.forRoot(), DndModule.forRoot(), SlimLoadingBarModule.forRoot(), DemoDndModule],
27 | declarations: [AppComponent, HomeComponent, SlimComponent, DndComponent, ToastComponent],
28 | providers: [{ provide: LocationStrategy, useClass: HashLocationStrategy }, ToastCommunicationService],
29 | bootstrap: [AppComponent]
30 | })
31 | export class AppModule { }
32 |
--------------------------------------------------------------------------------
/src/app/app.routing.ts:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2016 Sergey Akopkokhyants
2 | // This project is licensed under the terms of the MIT license.
3 | // https://github.com/akserg
4 |
5 | import { ModuleWithProviders } from '@angular/core';
6 | import { Routes, RouterModule } from '@angular/router';
7 |
8 | import { HomeComponent } from './home/home.component';
9 | import { SlimComponent } from './slim/slim.component';
10 | import { DndComponent } from './dnd/dnd.component';
11 | import { ToastComponent } from './toast/toast.component';
12 |
13 | const appRoutes: Routes = [
14 | {path: '', component: HomeComponent},
15 | {path: 'toasty', component: ToastComponent},
16 | {path: 'dnd', component: DndComponent},
17 | {path: 'slim', component: SlimComponent}
18 | ];
19 |
20 | export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
21 |
--------------------------------------------------------------------------------
/src/app/dnd/custom-data-dnd.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from '@angular/core';
2 |
3 | @Component({
4 | selector: 'custom-data-dnd',
5 | template: `
6 |
Transfer custom data in Drag-and-Drop
7 |
8 |
9 |
10 |
Available to drag
11 |
12 |
13 |
14 |
Drag Me
15 |
{{transferData | json}}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
Place to drop (Items:{{receivedData.length}})
24 |
25 |
0" *ngFor="let data of receivedData">{{data | json}}
26 |
27 |
28 |
29 |
`
30 | })
31 | export class CustomDataDndComponent {
32 | transferData: Object = {id: 1, msg: 'Hello'};
33 | receivedData: Array = [];
34 |
35 | transferDataSuccess($event: any) {
36 | this.receivedData.push($event);
37 | }
38 | }
--------------------------------------------------------------------------------
/src/app/dnd/custom-function-dnd.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'custom-function-dnd',
5 | template: `
6 | Use a custom function to determine where dropping is allowed
7 |
8 |
9 |
10 |
Available to drag
11 |
22 |
23 |
24 |
25 |
allowDropFunction(baseInteger: any): any {{ '{' }}
26 | return (dragData: any) => dragData % baseInteger === 0;
27 | {{ '}' }}
28 |
29 |
30 |
31 |
32 | Multiples of
33 |
34 | only
35 |
36 |
37 |
dragData = {{item}}
38 |
39 |
40 |
41 |
42 |
43 |
44 | Multiples of
45 |
46 | only
47 |
48 |
49 |
dragData = {{item}}
50 |
51 |
52 |
53 |
54 |
55 |
56 | `
57 | })
58 | export class CustomFunctionDndComponent {
59 | box1Integer: number = 3;
60 | box2Integer: number = 10;
61 |
62 | box1Items: string[] = [];
63 | box2Items: string[] = [];
64 |
65 | allowDropFunction(baseInteger: number): any {
66 | return (dragData: any) => dragData % baseInteger === 0;
67 | }
68 |
69 | addTobox1Items($event: any) {
70 | this.box1Items.push($event.dragData);
71 | }
72 |
73 | addTobox2Items($event: any) {
74 | this.box2Items.push($event.dragData);
75 | }
76 | }
--------------------------------------------------------------------------------
/src/app/dnd/demo-dnd.module.ts:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2016 Sergey Akopkokhyants
2 | // This project is licensed under the terms of the MIT license.
3 | // https://github.com/akserg
4 |
5 | import { NgModule } from '@angular/core';
6 | import { BrowserModule } from '@angular/platform-browser';
7 | import { FormsModule } from '@angular/forms';
8 |
9 | import { DndModule } from 'ng2-dnd';
10 |
11 | import { SimpleDndComponent } from './simple-dnd.component';
12 | import { ZoneDndComponent } from './zone-dnd.component';
13 | import { CustomDataDndComponent } from './custom-data-dnd.component';
14 | import { CustomFunctionDndComponent } from './custom-function-dnd.component';
15 | import { ShoppingBasketDndComponent } from './shopping-basket-dnd.component';
16 |
17 | import { SimpleSortableComponent } from './simple-sortable.component';
18 | import { MultiSortableComponent } from './multi-sortable.component';
19 | import { RecycleMultiSortableComponent } from './recycle-multi-sortable.component';
20 | import { EmbeddedSortableComponent} from './embedded-sortable.component';
21 | import { SimpleSortableCopyComponent } from './simple-sortable-copy.component';
22 |
23 | const dndComponents = [SimpleDndComponent, ZoneDndComponent, CustomDataDndComponent, CustomFunctionDndComponent, ShoppingBasketDndComponent];
24 | const sortableComponents = [SimpleSortableComponent, MultiSortableComponent, RecycleMultiSortableComponent, EmbeddedSortableComponent, SimpleSortableCopyComponent];
25 |
26 | @NgModule({
27 | imports: [BrowserModule, FormsModule, DndModule.forRoot()],
28 | declarations: [...dndComponents, ...sortableComponents],
29 | exports: [...dndComponents, ...sortableComponents]
30 | })
31 | export class DemoDndModule { }
--------------------------------------------------------------------------------
/src/app/dnd/dnd.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/app/dnd/dnd.component.ts:
--------------------------------------------------------------------------------
1 | // // Copyright (C) 2016 Sergey Akopkokhyants
2 | // // This project is licensed under the terms of the MIT license.
3 | // // https://github.com/akserg
4 |
5 | import {Component, Injectable} from '@angular/core';
6 |
7 | @Component({
8 | selector: 'demo-dnd',
9 | templateUrl: './dnd.component.html'
10 | })
11 | export class DndComponent {}
12 |
--------------------------------------------------------------------------------
/src/app/dnd/embedded-sortable.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from '@angular/core';
2 |
3 | @Component({
4 | selector: 'embedded-sortable',
5 | template: `
6 | Move items between multi list sortable containers
7 |
8 |
9 | Drag Containers
10 |
11 |
14 |
16 |
17 | {{container.id}} - {{container.name}}
18 |
19 |
20 |
21 | - {{widget.name}}
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
Widgets
33 |
34 |
35 |
36 | {{widget.name}}
37 |
38 |
39 |
40 |
41 |
42 |
`
43 | })
44 | export class EmbeddedSortableComponent {
45 | dragOperation: boolean = false;
46 |
47 | containers: Array = [
48 | new Container(1, 'Container 1', [new Widget('1'), new Widget('2')]),
49 | new Container(2, 'Container 2', [new Widget('3'), new Widget('4')]),
50 | new Container(3, 'Container 3', [new Widget('5'), new Widget('6')])
51 | ];
52 |
53 | widgets: Array = [];
54 | addTo($event: any) {
55 | if ($event) {
56 | this.widgets.push($event.dragData);
57 | }
58 | }
59 | }
60 |
61 | class Container {
62 | constructor(public id: number, public name: string, public widgets: Array) {}
63 | }
64 |
65 | class Widget {
66 | constructor(public name: string) {}
67 | }
--------------------------------------------------------------------------------
/src/app/dnd/multi-sortable.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'multi-sortable',
5 | template: `
6 | Multi list sortable
7 |
8 |
9 |
10 |
11 | Available boxers
12 |
13 |
18 |
19 |
20 |
21 |
22 |
23 | First Team
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 | Second Team
36 |
37 |
42 |
43 |
44 |
`
45 | })
46 | export class MultiSortableComponent {
47 | listBoxers: Array = ['Sugar Ray Robinson', 'Muhammad Ali', 'George Foreman', 'Joe Frazier', 'Jake LaMotta', 'Joe Louis', 'Jack Dempsey', 'Rocky Marciano', 'Mike Tyson', 'Oscar De La Hoya'];
48 | listTeamOne: Array = [];
49 | listTeamTwo: Array = [];
50 | }
--------------------------------------------------------------------------------
/src/app/dnd/recycle-multi-sortable.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from '@angular/core';
2 |
3 | @Component({
4 | selector: 'recycle-multi-sortable',
5 | template: `
6 | Simple sortable With Drop into recycle bin
7 |
8 |
9 |
10 |
11 | Favorite drinks
12 |
13 |
19 |
20 |
21 |
22 |
23 |
24 | Recycle bin: Drag into me to delete it
25 |
26 |
27 |
28 | Recycled: {{listRecycled.toString()}}
29 |
30 |
31 |
`
32 | })
33 | export class RecycleMultiSortableComponent {
34 | listOne: Array = ['Coffee', 'Orange Juice', 'Red Wine', 'Unhealty drink!', 'Water'];
35 | listRecycled: Array = [];
36 | }
--------------------------------------------------------------------------------
/src/app/dnd/shopping-basket-dnd.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'shoping-basket-dnd',
5 | template: `
6 | Drag-and-Drop - Shopping basket
7 |
8 |
9 |
10 |
11 |
Available products
12 |
13 |
0" [dragData]="product" (onDragSuccess)="orderedProduct($event)" [dropZones]="['demo1']">
15 |
16 |
{{product.name}} - \${{product.cost}}
(available: {{product.quantity}})
17 |
0">{{product.name}}
(NOT available)
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
Shopping Basket
(to pay: \${{totalCost()}})
26 |
27 |
28 |
29 | {{product.name}}
(ordered: {{product.quantity}}
cost: \${{product.cost * product.quantity}})
30 |
31 |
32 |
33 |
34 |
35 |
`
36 | })
37 | export class ShoppingBasketDndComponent {
38 | availableProducts: Array = [];
39 | shoppingBasket: Array = [];
40 |
41 | constructor() {
42 | this.availableProducts.push(new Product('Blue Shoes', 3, 35));
43 | this.availableProducts.push(new Product('Good Jacket', 1, 90));
44 | this.availableProducts.push(new Product('Red Shirt', 5, 12));
45 | this.availableProducts.push(new Product('Blue Jeans', 4, 60));
46 | }
47 |
48 | orderedProduct($event: any) {
49 | let orderedProduct: Product = $event.dragData;
50 | orderedProduct.quantity--;
51 | }
52 |
53 | addToBasket($event: any) {
54 | let newProduct: Product = $event.dragData;
55 | for (let indx in this.shoppingBasket) {
56 | let product: Product = this.shoppingBasket[indx];
57 | if (product.name === newProduct.name) {
58 | product.quantity++;
59 | return;
60 | }
61 | }
62 | this.shoppingBasket.push(new Product(newProduct.name, 1, newProduct.cost));
63 | this.shoppingBasket.sort((a: Product, b: Product) => {
64 | return a.name.localeCompare(b.name);
65 | });
66 | }
67 |
68 | totalCost(): number {
69 | let cost: number = 0;
70 | for (let indx in this.shoppingBasket) {
71 | let product: Product = this.shoppingBasket[indx];
72 | cost += (product.cost * product.quantity);
73 | }
74 | return cost;
75 | }
76 | }
77 |
78 | class Product {
79 | constructor(public name: string, public quantity: number, public cost: number) {}
80 | }
--------------------------------------------------------------------------------
/src/app/dnd/simple-dnd.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from '@angular/core';
2 |
3 | @Component({
4 | selector: 'simple-dnd',
5 | template: `
6 | Simple Drag-and-Drop
7 |
8 |
9 |
10 |
Available to drag
11 |
18 |
19 |
20 |
21 |
22 |
Place to drop
23 |
24 |
Item was dropped here
25 |
26 |
27 |
28 |
`
29 | })
30 | export class SimpleDndComponent {
31 | simpleDrop: any = null;
32 | }
--------------------------------------------------------------------------------
/src/app/dnd/simple-sortable-copy.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from '@angular/core';
2 |
3 | @Component({
4 | selector: 'simple-sortable-copy',
5 | template: `
6 | Simple sortable With Drop into something, without delete it
7 |
8 |
9 |
11 |
Source List
12 |
13 |
14 | - {{source.name}}
17 |
18 |
19 |
20 |
21 |
22 |
23 |
Target List
24 |
25 |
26 | -
27 | {{target.name}}
28 |
29 |
30 |
31 |
32 |
33 |
`
34 | })
35 | export class SimpleSortableCopyComponent {
36 |
37 | sourceList: Widget[] = [
38 | new Widget('1'), new Widget('2'),
39 | new Widget('3'), new Widget('4'),
40 | new Widget('5'), new Widget('6')
41 | ];
42 |
43 | targetList: Widget[] = [];
44 | addTo($event: any) {
45 | this.targetList.push($event.dragData);
46 | }
47 | }
48 |
49 | class Widget {
50 | constructor(public name: string) {}
51 | }
--------------------------------------------------------------------------------
/src/app/dnd/simple-sortable.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from '@angular/core';
2 |
3 | @Component({
4 | selector: 'simple-sortable',
5 | template: `
6 | Simple sortable
7 |
8 |
9 |
10 |
11 | Favorite drinks
12 |
13 |
18 |
19 |
20 |
21 |
22 |
23 | My prefences:
24 | {{i + 1}}) {{item}}
25 |
26 |
27 |
28 |
`
29 | })
30 | export class SimpleSortableComponent {
31 | listOne: Array = ['Coffee', 'Orange Juice', 'Red Wine', 'Unhealty drink!', 'Water'];
32 | }
--------------------------------------------------------------------------------
/src/app/dnd/zone-dnd.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from '@angular/core';
2 |
3 | @Component({
4 | selector: 'zone-dnd',
5 | template: `
6 | Restricted Drag-and-Drop with zones
7 |
8 |
9 |
10 |
Available to drag
11 |
12 |
13 |
14 |
Drag Me
15 |
Zone 1 only
16 |
17 |
18 |
19 |
20 |
21 |
22 |
Available to drag
23 |
24 |
25 |
26 |
Drag Me
27 |
Zone 1 & 2
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
Zone 1
36 |
37 |
Item was dropped here
38 |
39 |
40 |
41 |
42 |
43 |
Zone 2
44 |
45 |
Item was dropped here
46 |
47 |
48 |
49 |
`
50 | })
51 | export class ZoneDndComponent {
52 | restrictedDrop1: any = null;
53 | restrictedDrop2: any = null;
54 | }
--------------------------------------------------------------------------------
/src/app/home/home.component.html:
--------------------------------------------------------------------------------
1 |
2 |
Welcome to Demo
3 |
There are features implemented on Angular 2:
4 |
9 |
--------------------------------------------------------------------------------
/src/app/home/home.component.ts:
--------------------------------------------------------------------------------
1 | // // Copyright (C) 2016 Sergey Akopkokhyants
2 | // // This project is licensed under the terms of the MIT license.
3 | // // https://github.com/akserg
4 |
5 | import { Component } from '@angular/core';
6 |
7 | @Component({
8 | selector: 'demo-home',
9 | templateUrl: './home.component.html'
10 | })
11 | export class HomeComponent { }
12 |
--------------------------------------------------------------------------------
/src/app/index.ts:
--------------------------------------------------------------------------------
1 | export * from './app.component';
2 | export * from './app.module';
3 | export * from './home/home.component';
4 | export * from './dnd/dnd.component';
5 | export * from './slim/slim.component';
6 | export * from './toast';
7 |
--------------------------------------------------------------------------------
/src/app/slim/slim.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/app/slim/slim.component.ts:
--------------------------------------------------------------------------------
1 | // // Copyright (C) 2016 Sergey Akopkokhyants
2 | // // This project is licensed under the terms of the MIT license.
3 | // // https://github.com/akserg
4 |
5 | import {Component} from '@angular/core';
6 |
7 | // import {Subject, Observable, Subscription} from 'rxjs/Rx';
8 |
9 | import {SlimLoadingBarService} from 'ng2-slim-loading-bar';
10 |
11 | @Component({
12 | selector: 'demo-slim',
13 | templateUrl: './slim.component.html'
14 | })
15 | export class SlimComponent {
16 |
17 | constructor(private slimLoader: SlimLoadingBarService) {}
18 |
19 | setProgres30() {
20 | this.slimLoader.progress = 30;
21 | }
22 |
23 | startProgress() {
24 | // We can listen when loading will be completed
25 | this.slimLoader.start(() => {
26 | console.log('Loading complete');
27 | });
28 | }
29 |
30 | completeProgress() {
31 | this.slimLoader.complete();
32 | }
33 |
34 | stopProgress() {
35 | this.slimLoader.stop();
36 | }
37 |
38 | resetProgress() {
39 | this.slimLoader.reset();
40 | }
41 |
42 | incrementProgress() {
43 | this.slimLoader.progress++;
44 | }
45 |
46 | changeProgressTo4px() {
47 | this.slimLoader.height = '4px';
48 | }
49 |
50 | changeProgressTo2px() {
51 | this.slimLoader.height = '2px';
52 | }
53 |
54 | changeProgressToBlue() {
55 | this.slimLoader.color = 'blue';
56 | }
57 |
58 | changeProgressToFirebrick() {
59 | this.slimLoader.color = 'firebrick';
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/app/toast/index.ts:
--------------------------------------------------------------------------------
1 | export { ToastComponent } from './toast.component';
2 | export { ToastCommunicationService } from './toast-communication.service';
--------------------------------------------------------------------------------
/src/app/toast/toast-communication.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Subject } from 'rxjs/Subject';
3 |
4 | /**
5 | * Service helps communicate between the ToastComponent and AppComponent.
6 | */
7 | @Injectable()
8 | export class ToastCommunicationService {
9 | // Observable string sources
10 | private positionSource = new Subject();
11 |
12 | // Observable string streams
13 | position$ = this.positionSource.asObservable();
14 |
15 | setPosition(position) {
16 | this.positionSource.next(position);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/app/toast/toast.component.ts:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2016 Sergey Akopkokhyants
2 | // This project is licensed under the terms of the MIT license.
3 | // https://github.com/akserg
4 |
5 | import { Component } from '@angular/core';
6 |
7 | import {Subject, Observable, Subscription} from 'rxjs/Rx';
8 |
9 | import {ToastyService, ToastyConfig, ToastOptions, ToastData} from 'ng2-toasty';
10 |
11 | import {ToastCommunicationService} from './toast-communication.service';
12 |
13 | @Component({
14 | selector: 'demo-toast',
15 | template: `
16 | `
73 | })
74 | export class ToastComponent {
75 |
76 | themes = [{
77 | name: 'Default Theme',
78 | code: 'default'
79 | }, {
80 | name: 'Material Design',
81 | code: 'material'
82 | }, {
83 | name: 'Bootstrap 3',
84 | code: 'bootstrap'
85 | }];
86 |
87 | types = [{
88 | name: 'Default',
89 | code: 'default',
90 | }, {
91 | name: 'Info',
92 | code: 'info'
93 | }, {
94 | name: 'Success',
95 | code: 'success'
96 | }, {
97 | name: 'Wait',
98 | code: 'wait'
99 | }, {
100 | name: 'Error',
101 | code: 'error'
102 | }, {
103 | name: 'Warning',
104 | code: 'warning'
105 | }];
106 |
107 | positions = [{
108 | name: 'Top Left',
109 | code: 'top-left',
110 | }, {
111 | name: 'Top Center',
112 | code: 'top-center',
113 | }, {
114 | name: 'Top Right',
115 | code: 'top-right',
116 | }, {
117 | name: 'Bottom Left',
118 | code: 'bottom-left',
119 | }, {
120 | name: 'Bottom Center',
121 | code: 'bottom-center',
122 | }, {
123 | name: 'Bottom Right',
124 | code: 'bottom-right',
125 | }, {
126 | name: 'Center Center',
127 | code: 'center-center',
128 | }];
129 |
130 | position: string = this.positions[5].code;
131 |
132 | options = {
133 | title: 'Toast It!',
134 | msg: 'Mmmm, tasties...',
135 | showClose: true,
136 | timeout: 5000,
137 | theme: this.themes[0].code,
138 | type: this.types[0].code
139 | };
140 |
141 | getTitle(num: number): string {
142 | return 'Countdown: ' + num;
143 | }
144 |
145 | getMessage(num: number): string {
146 | return 'Seconds left: ' + num;
147 | }
148 |
149 | constructor(private toastyService: ToastyService, private toastCommunicationService: ToastCommunicationService) { }
150 |
151 | newToast() {
152 | let toastOptions: ToastOptions = {
153 | title: this.options.title,
154 | msg: this.options.msg,
155 | showClose: this.options.showClose,
156 | timeout: this.options.timeout,
157 | theme: this.options.theme,
158 | // position: this.options.position,
159 | onAdd: (toast: ToastData) => {
160 | console.log('Toast ' + toast.id + ' has been added!');
161 | },
162 | onRemove: function(toast: ToastData) {
163 | console.log('Toast ' + toast.id + ' has been removed!');
164 | }
165 | };
166 |
167 | switch (this.options.type) {
168 | case 'default': this.toastyService.default(toastOptions); break;
169 | case 'info': this.toastyService.info(toastOptions); break;
170 | case 'success': this.toastyService.success(toastOptions); break;
171 | case 'wait': this.toastyService.wait(toastOptions); break;
172 | case 'error': this.toastyService.error(toastOptions); break;
173 | case 'warning': this.toastyService.warning(toastOptions); break;
174 | }
175 | }
176 |
177 | newCountdownToast() {
178 | let interval = 1000;
179 | let seconds = this.options.timeout / 1000;
180 | let subscription: Subscription;
181 |
182 | let toastOptions: ToastOptions = {
183 | title: this.getTitle(seconds || 0),
184 | msg: this.getMessage(seconds || 0),
185 | showClose: this.options.showClose,
186 | timeout: this.options.timeout,
187 | theme: this.options.theme,
188 | onAdd: (toast: ToastData) => {
189 | console.log('Toast ' + toast.id + ' has been added!');
190 | // Run the timer with 1 second iterval
191 | let observable = Observable.interval(interval).take(seconds);
192 | // Start listen seconds bit
193 | subscription = observable.subscribe((count: number) => {
194 | // Update title
195 | toast.title = this.getTitle(seconds - count - 1 || 0);
196 | // Update message
197 | toast.msg = this.getMessage(seconds - count - 1 || 0);
198 | });
199 |
200 | },
201 | onRemove: function(toast: ToastData) {
202 | console.log('Toast ' + toast.id + ' has been removed!');
203 | // Stop listenning
204 | subscription.unsubscribe();
205 | }
206 | };
207 |
208 | switch (this.options.type) {
209 | case 'default': this.toastyService.default(toastOptions); break;
210 | case 'info': this.toastyService.info(toastOptions); break;
211 | case 'success': this.toastyService.success(toastOptions); break;
212 | case 'wait': this.toastyService.wait(toastOptions); break;
213 | case 'error': this.toastyService.error(toastOptions); break;
214 | case 'warning': this.toastyService.warning(toastOptions); break;
215 | }
216 | }
217 |
218 | clearToasties() {
219 | this.toastyService.clearAll();
220 | }
221 |
222 | changePosition($event) {
223 | this.position = $event;
224 | // Update position of the Toasty Component
225 | this.toastCommunicationService.setPosition(this.position);
226 | }
227 |
228 | }
229 |
--------------------------------------------------------------------------------
/src/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akserg/ng2-webpack-demo/8e524bc87a41dae716a288306d76afda610fe1e7/src/assets/.gitkeep
--------------------------------------------------------------------------------
/src/assets/.npmignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akserg/ng2-webpack-demo/8e524bc87a41dae716a288306d76afda610fe1e7/src/assets/.npmignore
--------------------------------------------------------------------------------
/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // The file contents for the current environment will overwrite these during build.
2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do
3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead.
4 | // The list of which env maps to which file can be found in `angular-cli.json`.
5 |
6 | export const environment = {
7 | production: false
8 | };
9 |
--------------------------------------------------------------------------------
/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akserg/ng2-webpack-demo/8e524bc87a41dae716a288306d76afda610fe1e7/src/favicon.ico
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Ng2WebpackDemo
6 |
7 |
8 |
9 |
10 |
12 |
13 |
14 | Loading...
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import './polyfills.ts';
2 |
3 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
4 | import { enableProdMode } from '@angular/core';
5 | import { environment } from './environments/environment';
6 | import { AppModule } from './app/app.module';
7 |
8 | if (environment.production) {
9 | enableProdMode();
10 | }
11 |
12 | platformBrowserDynamic().bootstrapModule(AppModule);
13 |
--------------------------------------------------------------------------------
/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | // This file includes polyfills needed by Angular 2 and is loaded before
2 | // the app. You can add your own extra polyfills to this file.
3 | import 'core-js/es6/symbol';
4 | import 'core-js/es6/object';
5 | import 'core-js/es6/function';
6 | import 'core-js/es6/parse-int';
7 | import 'core-js/es6/parse-float';
8 | import 'core-js/es6/number';
9 | import 'core-js/es6/math';
10 | import 'core-js/es6/string';
11 | import 'core-js/es6/date';
12 | import 'core-js/es6/array';
13 | import 'core-js/es6/regexp';
14 | import 'core-js/es6/map';
15 | import 'core-js/es6/set';
16 | import 'core-js/es6/reflect';
17 |
18 | import 'core-js/es7/reflect';
19 | import 'zone.js/dist/zone';
20 |
--------------------------------------------------------------------------------
/src/skeleton.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Skeleton V2.0.4
3 | * Copyright 2014, Dave Gamache
4 | * www.getskeleton.com
5 | * Free to use under the MIT license.
6 | * http://www.opensource.org/licenses/mit-license.php
7 | * 12/29/2014
8 | */
9 |
10 |
11 | /* Table of contents
12 | ––––––––––––––––––––––––––––––––––––––––––––––––––
13 | - Grid
14 | - Base Styles
15 | - Typography
16 | - Links
17 | - Buttons
18 | - Forms
19 | - Lists
20 | - Code
21 | - Tables
22 | - Spacing
23 | - Utilities
24 | - Clearing
25 | - Media Queries
26 | */
27 |
28 |
29 | /* Grid
30 | –––––––––––––––––––––––––––––––––––––––––––––––––– */
31 | .container {
32 | position: relative;
33 | width: 100%;
34 | max-width: 960px;
35 | margin: 0 auto;
36 | padding: 0 20px;
37 | box-sizing: border-box; }
38 | .column,
39 | .columns {
40 | width: 100%;
41 | float: left;
42 | box-sizing: border-box; }
43 |
44 | /* For devices larger than 400px */
45 | @media (min-width: 400px) {
46 | .container {
47 | width: 85%;
48 | padding: 0; }
49 | }
50 |
51 | /* For devices larger than 550px */
52 | @media (min-width: 550px) {
53 | .container {
54 | width: 80%; }
55 | .column,
56 | .columns {
57 | margin-left: 4%; }
58 | .column:first-child,
59 | .columns:first-child {
60 | margin-left: 0; }
61 |
62 | .one.column,
63 | .one.columns { width: 4.66666666667%; }
64 | .two.columns { width: 13.3333333333%; }
65 | .three.columns { width: 22%; }
66 | .four.columns { width: 30.6666666667%; }
67 | .five.columns { width: 39.3333333333%; }
68 | .six.columns { width: 48%; }
69 | .seven.columns { width: 56.6666666667%; }
70 | .eight.columns { width: 65.3333333333%; }
71 | .nine.columns { width: 74.0%; }
72 | .ten.columns { width: 82.6666666667%; }
73 | .eleven.columns { width: 91.3333333333%; }
74 | .twelve.columns { width: 100%; margin-left: 0; }
75 |
76 | .one-third.column { width: 30.6666666667%; }
77 | .two-thirds.column { width: 65.3333333333%; }
78 |
79 | .one-half.column { width: 48%; }
80 |
81 | /* Offsets */
82 | .offset-by-one.column,
83 | .offset-by-one.columns { margin-left: 8.66666666667%; }
84 | .offset-by-two.column,
85 | .offset-by-two.columns { margin-left: 17.3333333333%; }
86 | .offset-by-three.column,
87 | .offset-by-three.columns { margin-left: 26%; }
88 | .offset-by-four.column,
89 | .offset-by-four.columns { margin-left: 34.6666666667%; }
90 | .offset-by-five.column,
91 | .offset-by-five.columns { margin-left: 43.3333333333%; }
92 | .offset-by-six.column,
93 | .offset-by-six.columns { margin-left: 52%; }
94 | .offset-by-seven.column,
95 | .offset-by-seven.columns { margin-left: 60.6666666667%; }
96 | .offset-by-eight.column,
97 | .offset-by-eight.columns { margin-left: 69.3333333333%; }
98 | .offset-by-nine.column,
99 | .offset-by-nine.columns { margin-left: 78.0%; }
100 | .offset-by-ten.column,
101 | .offset-by-ten.columns { margin-left: 86.6666666667%; }
102 | .offset-by-eleven.column,
103 | .offset-by-eleven.columns { margin-left: 95.3333333333%; }
104 |
105 | .offset-by-one-third.column,
106 | .offset-by-one-third.columns { margin-left: 34.6666666667%; }
107 | .offset-by-two-thirds.column,
108 | .offset-by-two-thirds.columns { margin-left: 69.3333333333%; }
109 |
110 | .offset-by-one-half.column,
111 | .offset-by-one-half.columns { margin-left: 52%; }
112 |
113 | }
114 |
115 |
116 | /* Base Styles
117 | –––––––––––––––––––––––––––––––––––––––––––––––––– */
118 | /* NOTE
119 | html is set to 62.5% so that all the REM measurements throughout Skeleton
120 | are based on 10px sizing. So basically 1.5rem = 15px :) */
121 | html {
122 | font-size: 62.5%; }
123 | body {
124 | font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */
125 | line-height: 1.6;
126 | font-weight: 400;
127 | font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
128 | color: #222; }
129 |
130 |
131 | /* Typography
132 | –––––––––––––––––––––––––––––––––––––––––––––––––– */
133 | h1, h2, h3, h4, h5, h6 {
134 | margin-top: 0;
135 | margin-bottom: 2rem;
136 | font-weight: 300; }
137 | h1 { font-size: 4.0rem; line-height: 1.2; letter-spacing: -.1rem;}
138 | h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; }
139 | h3 { font-size: 3.0rem; line-height: 1.3; letter-spacing: -.1rem; }
140 | h4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; }
141 | h5 { font-size: 1.8rem; line-height: 1.5; letter-spacing: -.05rem; }
142 | h6 { font-size: 1.5rem; line-height: 1.6; letter-spacing: 0; }
143 |
144 | /* Larger than phablet */
145 | @media (min-width: 550px) {
146 | h1 { font-size: 5.0rem; }
147 | h2 { font-size: 4.2rem; }
148 | h3 { font-size: 3.6rem; }
149 | h4 { font-size: 3.0rem; }
150 | h5 { font-size: 2.4rem; }
151 | h6 { font-size: 1.5rem; }
152 | }
153 |
154 | p {
155 | margin-top: 0; }
156 |
157 |
158 | /* Links
159 | –––––––––––––––––––––––––––––––––––––––––––––––––– */
160 | a {
161 | color: #1EAEDB; }
162 | a:hover {
163 | color: #0FA0CE; }
164 |
165 |
166 | /* Buttons
167 | –––––––––––––––––––––––––––––––––––––––––––––––––– */
168 | .button,
169 | button,
170 | input[type="submit"],
171 | input[type="reset"],
172 | input[type="button"] {
173 | display: inline-block;
174 | height: 38px;
175 | padding: 0 30px;
176 | color: #555;
177 | text-align: center;
178 | font-size: 11px;
179 | font-weight: 600;
180 | line-height: 38px;
181 | letter-spacing: .1rem;
182 | text-transform: uppercase;
183 | text-decoration: none;
184 | white-space: nowrap;
185 | background-color: transparent;
186 | border-radius: 4px;
187 | border: 1px solid #bbb;
188 | cursor: pointer;
189 | box-sizing: border-box; }
190 | .button:hover,
191 | button:hover,
192 | input[type="submit"]:hover,
193 | input[type="reset"]:hover,
194 | input[type="button"]:hover,
195 | .button:focus,
196 | button:focus,
197 | input[type="submit"]:focus,
198 | input[type="reset"]:focus,
199 | input[type="button"]:focus {
200 | color: #333;
201 | border-color: #888;
202 | outline: 0; }
203 | .button.button-primary,
204 | button.button-primary,
205 | input[type="submit"].button-primary,
206 | input[type="reset"].button-primary,
207 | input[type="button"].button-primary {
208 | color: #FFF;
209 | background-color: #33C3F0;
210 | border-color: #33C3F0; }
211 | .button.button-primary:hover,
212 | button.button-primary:hover,
213 | input[type="submit"].button-primary:hover,
214 | input[type="reset"].button-primary:hover,
215 | input[type="button"].button-primary:hover,
216 | .button.button-primary:focus,
217 | button.button-primary:focus,
218 | input[type="submit"].button-primary:focus,
219 | input[type="reset"].button-primary:focus,
220 | input[type="button"].button-primary:focus {
221 | color: #FFF;
222 | background-color: #1EAEDB;
223 | border-color: #1EAEDB; }
224 |
225 |
226 | /* Forms
227 | –––––––––––––––––––––––––––––––––––––––––––––––––– */
228 | input[type="email"],
229 | input[type="number"],
230 | input[type="search"],
231 | input[type="text"],
232 | input[type="tel"],
233 | input[type="url"],
234 | input[type="password"],
235 | textarea,
236 | select {
237 | height: 38px;
238 | padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */
239 | background-color: #fff;
240 | border: 1px solid #D1D1D1;
241 | border-radius: 4px;
242 | box-shadow: none;
243 | box-sizing: border-box; }
244 | /* Removes awkward default styles on some inputs for iOS */
245 | input[type="email"],
246 | input[type="number"],
247 | input[type="search"],
248 | input[type="text"],
249 | input[type="tel"],
250 | input[type="url"],
251 | input[type="password"],
252 | textarea {
253 | -webkit-appearance: none;
254 | -moz-appearance: none;
255 | appearance: none; }
256 | textarea {
257 | min-height: 65px;
258 | padding-top: 6px;
259 | padding-bottom: 6px; }
260 | input[type="email"]:focus,
261 | input[type="number"]:focus,
262 | input[type="search"]:focus,
263 | input[type="text"]:focus,
264 | input[type="tel"]:focus,
265 | input[type="url"]:focus,
266 | input[type="password"]:focus,
267 | textarea:focus,
268 | select:focus {
269 | border: 1px solid #33C3F0;
270 | outline: 0; }
271 | label,
272 | legend {
273 | display: block;
274 | margin-bottom: .5rem;
275 | font-weight: 600; }
276 | fieldset {
277 | padding: 0;
278 | border-width: 0; }
279 | input[type="checkbox"],
280 | input[type="radio"] {
281 | display: inline; }
282 | label > .label-body {
283 | display: inline-block;
284 | margin-left: .5rem;
285 | font-weight: normal; }
286 |
287 |
288 | /* Lists
289 | –––––––––––––––––––––––––––––––––––––––––––––––––– */
290 | ul {
291 | list-style: circle inside; }
292 | ol {
293 | list-style: decimal inside; }
294 | ol, ul {
295 | padding-left: 0;
296 | margin-top: 0; }
297 | ul ul,
298 | ul ol,
299 | ol ol,
300 | ol ul {
301 | margin: 1.5rem 0 1.5rem 3rem;
302 | font-size: 90%; }
303 | li {
304 | margin-bottom: 1rem; }
305 |
306 |
307 | /* Code
308 | –––––––––––––––––––––––––––––––––––––––––––––––––– */
309 | code {
310 | padding: .2rem .5rem;
311 | margin: 0 .2rem;
312 | font-size: 90%;
313 | white-space: nowrap;
314 | background: #F1F1F1;
315 | border: 1px solid #E1E1E1;
316 | border-radius: 4px; }
317 | pre > code {
318 | display: block;
319 | padding: 1rem 1.5rem;
320 | white-space: pre; }
321 |
322 |
323 | /* Tables
324 | –––––––––––––––––––––––––––––––––––––––––––––––––– */
325 | th,
326 | td {
327 | padding: 12px 15px;
328 | text-align: left;
329 | border-bottom: 1px solid #E1E1E1; }
330 | th:first-child,
331 | td:first-child {
332 | padding-left: 0; }
333 | th:last-child,
334 | td:last-child {
335 | padding-right: 0; }
336 |
337 |
338 | /* Spacing
339 | –––––––––––––––––––––––––––––––––––––––––––––––––– */
340 | button,
341 | .button {
342 | margin-bottom: 1rem; }
343 | input,
344 | textarea,
345 | select,
346 | fieldset {
347 | margin-bottom: 1.5rem; }
348 | pre,
349 | blockquote,
350 | dl,
351 | figure,
352 | table,
353 | p,
354 | ul,
355 | ol,
356 | form {
357 | margin-bottom: 2.5rem; }
358 |
359 |
360 | /* Utilities
361 | –––––––––––––––––––––––––––––––––––––––––––––––––– */
362 | .u-full-width {
363 | width: 100%;
364 | box-sizing: border-box; }
365 | .u-max-full-width {
366 | max-width: 100%;
367 | box-sizing: border-box; }
368 | .u-pull-right {
369 | float: right; }
370 | .u-pull-left {
371 | float: left; }
372 |
373 |
374 | /* Misc
375 | –––––––––––––––––––––––––––––––––––––––––––––––––– */
376 | hr {
377 | margin-top: 3rem;
378 | margin-bottom: 3.5rem;
379 | border-width: 0;
380 | border-top: 1px solid #E1E1E1; }
381 |
382 |
383 | /* Clearing
384 | –––––––––––––––––––––––––––––––––––––––––––––––––– */
385 |
386 | /* Self Clearing Goodness */
387 | .container:after,
388 | .row:after,
389 | .u-cf {
390 | content: "";
391 | display: table;
392 | clear: both; }
393 |
394 |
395 | /* Media Queries
396 | –––––––––––––––––––––––––––––––––––––––––––––––––– */
397 | /*
398 | Note: The best way to structure the use of media queries is to create the queries
399 | near the relevant code. For example, if you wanted to change the styles for buttons
400 | on small devices, paste the mobile query code up in the buttons section and style it
401 | there.
402 | */
403 |
404 |
405 | /* Larger than mobile */
406 | @media (min-width: 400px) {}
407 |
408 | /* Larger than phablet (also point when grid becomes active) */
409 | @media (min-width: 550px) {}
410 |
411 | /* Larger than tablet */
412 | @media (min-width: 750px) {}
413 |
414 | /* Larger than desktop */
415 | @media (min-width: 1000px) {}
416 |
417 | /* Larger than Desktop HD */
418 | @media (min-width: 1200px) {}
--------------------------------------------------------------------------------
/src/styles.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding: 0;
3 | margin: 0;
4 | }
5 |
6 | header {
7 | border-bottom: 1px solid #eee;
8 | height: 6.5rem;
9 | }
10 |
11 | .navbar-list {
12 | list-style: none;
13 | margin-bottom: 0;
14 | }
15 |
16 | .navbar-item {
17 | margin-bottom: 0;
18 | position: relative;
19 | }
20 |
21 | .navbar-link {
22 | text-transform: uppercase;
23 | font-size: 11px;
24 | font-weight: 600;
25 | letter-spacing: .2rem;
26 | margin-right: 35px;
27 | text-decoration: none;
28 | line-height: 6.5rem;
29 | color: #222;
30 | }
31 |
32 | small {
33 | font-size: 6px;
34 | opacity: .2;
35 | }
36 |
37 | code {
38 | word-break: break-word;
39 | }
40 |
41 | @media (max-width: 400px) {
42 | header {
43 | display: none;
44 | }
45 | }
--------------------------------------------------------------------------------
/src/test.ts:
--------------------------------------------------------------------------------
1 | import './polyfills.ts';
2 |
3 | import 'zone.js/dist/long-stack-trace-zone';
4 | import 'zone.js/dist/proxy.js';
5 | import 'zone.js/dist/sync-test';
6 | import 'zone.js/dist/jasmine-patch';
7 | import 'zone.js/dist/async-test';
8 | import 'zone.js/dist/fake-async-test';
9 | import { getTestBed } from '@angular/core/testing';
10 | import {
11 | BrowserDynamicTestingModule,
12 | platformBrowserDynamicTesting
13 | } from '@angular/platform-browser-dynamic/testing';
14 |
15 | // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
16 | declare var __karma__: any;
17 | declare var require: any;
18 |
19 | // Prevent Karma from running prematurely.
20 | __karma__.loaded = function () {};
21 |
22 | // First, initialize the Angular testing environment.
23 | getTestBed().initTestEnvironment(
24 | BrowserDynamicTestingModule,
25 | platformBrowserDynamicTesting()
26 | );
27 | // Then we find all the tests.
28 | let context = require.context('./', true, /\.spec\.ts$/);
29 | // And load the modules.
30 | context.keys().map(context);
31 | // Finally, start Karma to run the tests.
32 | __karma__.start();
33 |
--------------------------------------------------------------------------------
/src/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": "",
4 | "declaration": false,
5 | "emitDecoratorMetadata": true,
6 | "experimentalDecorators": true,
7 | "lib": ["es6", "dom"],
8 | "mapRoot": "./",
9 | "module": "es6",
10 | "moduleResolution": "node",
11 | "outDir": "../dist/out-tsc",
12 | "sourceMap": true,
13 | "target": "es5",
14 | "typeRoots": [
15 | "../node_modules/@types"
16 | ]
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/typings.d.ts:
--------------------------------------------------------------------------------
1 | // Typings reference file, see links for more information
2 | // https://github.com/typings/typings
3 | // https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html
4 |
5 | declare var System: any;
6 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": [
3 | "node_modules/codelyzer"
4 | ],
5 | "rules": {
6 | "class-name": true,
7 | "comment-format": [
8 | true,
9 | "check-space"
10 | ],
11 | "curly": true,
12 | "eofline": true,
13 | "forin": true,
14 | "indent": [
15 | true,
16 | "spaces"
17 | ],
18 | "label-position": true,
19 | "max-line-length": [
20 | true,
21 | 140
22 | ],
23 | "member-access": false,
24 | "member-ordering": [
25 | true,
26 | "static-before-instance",
27 | "variables-before-functions"
28 | ],
29 | "no-arg": true,
30 | "no-bitwise": true,
31 | "no-console": [
32 | true,
33 | "debug",
34 | "info",
35 | "time",
36 | "timeEnd",
37 | "trace"
38 | ],
39 | "no-construct": true,
40 | "no-debugger": true,
41 | "no-duplicate-variable": true,
42 | "no-empty": false,
43 | "no-eval": true,
44 | "no-inferrable-types": true,
45 | "no-shadowed-variable": true,
46 | "no-string-literal": false,
47 | "no-switch-case-fall-through": true,
48 | "no-trailing-whitespace": true,
49 | "no-unused-expression": true,
50 | "no-use-before-declare": true,
51 | "no-var-keyword": true,
52 | "object-literal-sort-keys": false,
53 | "one-line": [
54 | true,
55 | "check-open-brace",
56 | "check-catch",
57 | "check-else",
58 | "check-whitespace"
59 | ],
60 | "quotemark": [
61 | true,
62 | "single"
63 | ],
64 | "radix": true,
65 | "semicolon": [
66 | "always"
67 | ],
68 | "triple-equals": [
69 | true,
70 | "allow-null-check"
71 | ],
72 | "typedef-whitespace": [
73 | true,
74 | {
75 | "call-signature": "nospace",
76 | "index-signature": "nospace",
77 | "parameter": "nospace",
78 | "property-declaration": "nospace",
79 | "variable-declaration": "nospace"
80 | }
81 | ],
82 | "variable-name": false,
83 | "whitespace": [
84 | true,
85 | "check-branch",
86 | "check-decl",
87 | "check-operator",
88 | "check-separator",
89 | "check-type"
90 | ],
91 |
92 | "directive-selector": [true, "attribute", "app", "camelCase"],
93 | "component-selector": [true, "element", "app", "kebab-case"],
94 | "use-input-property-decorator": true,
95 | "use-output-property-decorator": true,
96 | "use-host-property-decorator": true,
97 | "no-input-rename": true,
98 | "no-output-rename": true,
99 | "use-life-cycle-interface": true,
100 | "use-pipe-transform-interface": true,
101 | "component-class-suffix": true,
102 | "directive-class-suffix": true,
103 | "no-access-missing-member": true,
104 | "templates-use-public": true,
105 | "invoke-injectable": true
106 | }
107 | }
108 |
--------------------------------------------------------------------------------