<!DOCTYPE html>
<html>
<head>
<base href="." />
<title>angular 5 + flex layout</title>
<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
* {box-sizing: border-box;}
my-app {
font-size: 1.2em;
}
input[type=checkbox] {
width: 20px;
height: 20px;
cursor: pointer;
}
</style>
<!-- polyfill(s) for older browsers -->
<script src="https://unpkg.com/core-js/client/shim.min.js"></script>
<script src="https://unpkg.com/zone.js@0.8.16?main=browser"></script>
<!--<script src="https://unpkg.com/reflect-metadata@0.1.10"></script>-->
<script src="https://unpkg.com/systemjs@0.20.18/dist/system.src.js"></script>
<script src="https://unpkg.com/web-animations-js@2.3.1"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function (err) { console.error(err); });
</script>
</head>
<body>
<my-app>
loading...
</my-app>
</body>
</html>
//our root app component
import { Component, NgModule, VERSION} from '@angular/core'
import { BrowserModule} from '@angular/platform-browser'
@Component({
selector: 'my-app',
template: `
<div class="gui" [appWindowResize]="windowSizeBreakpoints" (windowWidthChanged)="setIsCompact($event)">
<div class="left-panel">
<h2 *ngIf="sizeOption >= 2">Left panel</h2>
<h2 *ngIf="sizeOption < 2">LP</h2>
</div>
<div class="main-area">
<h2>Main area</h2>
<p>Resize this window by toggling side panels in the viewer.</p>
<p>The breakpoints are 300px and 500px.</p>
</div>
<div class="right-panel" *ngIf="sizeOption >= 1"><h2>Right panel</h2></div>
</div>
`,
styles: [`
:host {
display: block;
height: 100%;
}
.gui {
display: flex;
width: 100%;
height: 100%;
}
.left-panel {
max-width: 200px;
flex-basis: 200px;
border-right: solid 2px #444;
padding: 0 1em;
}
.right-panel {
max-width: 200px;
flex-basis: 100px;
border-left: solid 2px #444;
padding: 0 1em;
}
.main-area {
flex-basis: 100%;
padding: 0 1em;
}
`]
})
export class AppComponent {
public isReadOnly: boolean = false;
public windowSizeBreakpoints = [300, 500];
/**
* The size options will be:
* 0: <300
* 1: 300-500
* 2: 500+
**/
public sizeOption: number = 2;
public setIsCompact(widthIdx) {
this.sizeOption = widthIdx;
}
}
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component';
import { WindowResizeDirective } from './windowresize.directive';
@NgModule({
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
],
declarations: [
AppComponent,
WindowResizeDirective,
],
providers: [
],
bootstrap: [AppComponent]
})
export class AppModule { }
(function (global) {
var angVer = '5.0.0-beta.6';
System.config({
transpiler: 'ts',
typescriptOptions: {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [ "es2015", "dom" ],
"module": "commonjs",
"moduleResolution": "node",
"noImplicitAny": true,
"sourceMap": true,
"suppressImplicitAnyIndexErrors": true,
"target": "es5"
},
meta: {
'typescript': {
"exports": "ts"
}
},
paths: {
'npm:': 'https://unpkg.com/',
'gh:': 'https://raw.githubusercontent.com/'
},
map: {
"app": "app",
"rxjs": "npm:rxjs@5.4.3",
"ts": "npm:plugin-typescript@7.1.0/lib/plugin.js",
"typescript": "npm:typescript@2.4.2/lib/typescript.js",
"@angular/core": "npm:@angular/core@" + angVer + "/bundles/core.umd.js",
"@angular/common": "npm:@angular/common@" + angVer + "/bundles/common.umd.js",
"@angular/compiler": "npm:@angular/compiler@" + angVer + "/bundles/compiler.umd.js",
"@angular/platform-browser": "npm:@angular/platform-browser@" + angVer + "/bundles/platform-browser.umd.js",
"@angular/platform-browser-dynamic": "npm:@angular/platform-browser-dynamic@" + angVer + "/bundles/platform-browser-dynamic.umd.js",
"@angular/http": "npm:@angular/http@" + angVer + "/bundles/http.umd.js",
"@angular/router": "npm:@angular/router@" + angVer + "/bundles/router.umd.js",
"@angular/forms": "npm:@angular/forms@" + angVer + "/bundles/forms.umd.js",
"@angular/animations": "npm:@angular/animations@" + angVer + "/bundles/animations.umd.js",
"@angular/animations/browser": "npm:@angular/animations@" + angVer + "/bundles/animations-browser.umd.js",
"@angular/platform-browser/animations": "npm:@angular/platform-browser@" + angVer + "/bundles/platform-browser-animations.umd.js",
"@angular/flex-layout": "npm:@angular/flex-layout@2.0.0-beta.9"
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
main: './main.ts',
defaultExtension: 'ts'
},
rxjs: {
defaultExtension: 'js'
}
}
});
if (!global.noBootstrap) { bootstrap(); }
// Bootstrap the `AppModule`(skip the `app/main.ts` that normally does this)
function bootstrap() {
// Stub out `app/main.ts` so System.import('app') doesn't fail if called in the index.html
System.set(System.normalizeSync('app/main.ts'), System.newModule({ }));
// bootstrap and launch the app (equivalent to standard main.ts)
Promise.all([
System.import('@angular/platform-browser-dynamic'),
System.import('app/app.module')
])
.then(function (imports) {
var platform = imports[0];
var app = imports[1];
platform.platformBrowserDynamic().bootstrapModule(app.AppModule);
})
.catch(function(err){ console.error(err); });
}
})(this);
import {
Directive,
ElementRef,
EventEmitter,
Inject,
Input,
NgZone,
Output,
} from '@angular/core';
import {DeferredPromise} from '@lucid/modeldeps/promise';
import {Debounce} from '@lucid/pipelinedeps/debounce';
// Callback debounce utility
function debounce<F extends(...args: any[]) => void>(f: F, timeout: number, target?: any): F {
let timer: number|undefined = undefined;
return (function(this: any, ...args: any[]) {
target = target || this;
timer && clearTimeout(timer);
timer = setTimeout(() => {
f.apply(target, args);
}, timeout);
}) as F;
}
@Directive({
selector: '[appWindowResize]',
host: {
'(window:resize)': 'onResize()',
}
})
export class WindowResizeDirective {
@Input() appWindowResize: number[] = [0];
@Output() windowWidthChanged: EventEmitter<number> = new EventEmitter<number>();
private widthIndex: number = -1;
private onResize = debounce(() => {
const offsetWidth = this.getWidth();
let widthIndex = this.appWindowResize.findIndex(width => width > offsetWidth);
widthIndex = (widthIndex + this.appWindowResize.length + 1) % (this.appWindowResize.length + 1);
if (this.widthIndex != widthIndex) {
this.widthIndex = widthIndex;
this.zone.run(() => {
this.windowWidthChanged.emit(widthIndex);
});
}
}, 200);
constructor(private elementRef: ElementRef, private zone: NgZone) {
this.onResize();
}
getWidth(): number {
return this.elementRef.nativeElement.offsetWidth;
}
}