Users/benfeely/projecting react (#1)
* Projection of dialog footer with buttons working. * Dialog working with projection! * React perf working reasonably well... * Fix bug in link name. * Updates to dependencies (cli). Failed to complete 'yarn update' (nx). * Trying to get react/mixed perf working... * React perf working. * Remove unused comment. * Cleaning up the triangle. * Cleaning up dots.
This commit is contained in:
Родитель
36533e4395
Коммит
a7ec6c6207
|
@ -20,7 +20,7 @@
|
|||
"testTsconfig": "../../../tsconfig.spec.json",
|
||||
"prefix": "app",
|
||||
"styles": [
|
||||
"styles.css"
|
||||
"styles.scss"
|
||||
],
|
||||
"scripts": [],
|
||||
"environmentSource": "environments/environment.ts",
|
||||
|
@ -45,7 +45,7 @@
|
|||
"testTsconfig": "../../../tsconfig.spec.json",
|
||||
"prefix": "app",
|
||||
"styles": [
|
||||
"styles.css"
|
||||
"styles.scss"
|
||||
],
|
||||
"scripts": [],
|
||||
"environmentSource": "environments/environment.ts",
|
||||
|
@ -104,8 +104,7 @@
|
|||
},
|
||||
"defaults": {
|
||||
"styleExt": "scss",
|
||||
"component": {
|
||||
},
|
||||
"component": {},
|
||||
"schematics": {
|
||||
"collection": "@nrwl/schematics"
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../dist/out-tsc/e2e/demo",
|
||||
"outDir": "../../../dist/out-tsc/e2e/demo-from-packages",
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"types": [
|
||||
|
@ -17,4 +17,4 @@
|
|||
"exclude": [
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,8 +1,22 @@
|
|||
<a routerLink="landing"><span class="test-class">Landing</span> <b>page</b></a>
|
||||
<!-- <DefaultButton text="React Button"></DefaultButton> -->
|
||||
<a routerLink="perf/angular">Angular Perf</a>
|
||||
<a routerLink="perf/mixed">Material Perf</a>
|
||||
<a routerLink="components/fabric">Fabric Components</a>
|
||||
<a routerLink="components/material">Material Components</a>
|
||||
<ul>
|
||||
<li>
|
||||
<a routerLink="landing">
|
||||
<span class="test-class">Landing</span>
|
||||
<b>page</b>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a routerLink="perf/angular">Angular Perf</a>
|
||||
</li>
|
||||
<li>
|
||||
<a routerLink="perf/mixed">React Perf</a>
|
||||
</li>
|
||||
<li>
|
||||
<a routerLink="components/fabric">Fabric Components</a>
|
||||
</li>
|
||||
<li>
|
||||
<a routerLink="components/material">Material Components</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<router-outlet></router-outlet>
|
||||
|
|
|
@ -1,7 +1,19 @@
|
|||
:host {
|
||||
display: block;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
a {
|
||||
margin-right: 10px;
|
||||
ul {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
padding: 0;
|
||||
|
||||
li {
|
||||
|
||||
a {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,9 +4,11 @@
|
|||
[style.height]="size"
|
||||
[style.left]="x"
|
||||
[style.top]="y"
|
||||
[class.hover]="hover"
|
||||
[style.color]="color"
|
||||
[style.background-color]="backgroundColor"
|
||||
(mouseenter)="onMouseEnter($event)"
|
||||
(mouseleave)="onMouseLeave($event)"
|
||||
>
|
||||
{{ text }}
|
||||
<ng-container *ngIf="textOverride">{{ textOverride }}</ng-container>
|
||||
<ng-container *ngIf="!textOverride"><ng-content></ng-content></ng-container>
|
||||
</div>
|
||||
|
|
|
@ -2,13 +2,6 @@
|
|||
display: block;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
background-color: #ddd;
|
||||
color: #222;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
:host div.hover {
|
||||
background-color: #0078D4;
|
||||
color: #fff;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core';
|
||||
// tslint:disable:no-output-rename
|
||||
import { ChangeDetectionStrategy, Component, Input, Output, EventEmitter } from '@angular/core';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-dot',
|
||||
|
@ -11,16 +13,14 @@ export class DotComponent {
|
|||
@Input() x: string;
|
||||
@Input() y: string;
|
||||
@Input() size: string;
|
||||
@Input() text: string;
|
||||
@Input() color: string;
|
||||
@Input() backgroundColor: string;
|
||||
@Input() textOverride: string;
|
||||
|
||||
hover = false;
|
||||
@Output('onMouseEnter') mouseEnter: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
|
||||
@Output('onMouseLeave') mouseLeave: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
|
||||
|
||||
onMouseEnter(ev) {
|
||||
this.hover = true;
|
||||
}
|
||||
|
||||
onMouseLeave(ev) {
|
||||
this.hover = false;
|
||||
}
|
||||
onMouseEnter = ev => this.mouseEnter.emit(ev as any);
|
||||
onMouseLeave = ev => this.mouseLeave.emit(ev as any);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
<!-- <fabric-button label="Stop Triangle" (onClick)="toggle()"></fabric-button> -->
|
||||
|
||||
<div class="container" [style.transform]="'scale(' + scale + ', 0.7)'">
|
||||
<app-dot
|
||||
*ngFor="let dot of dots"
|
||||
[size]="dot.size"
|
||||
[x]="dot.x"
|
||||
[y]="dot.y"
|
||||
[text]="seconds"
|
||||
></app-dot>
|
||||
<ng-container *ngFor="let dot of dots">
|
||||
<ng-container *ngTemplateOutlet="dotTemplate; context: { dot: dot, text: seconds }"></ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
:host {
|
||||
display: block;
|
||||
position: relative;
|
||||
|
||||
.container {
|
||||
position: absolute;
|
||||
|
@ -8,6 +9,6 @@
|
|||
top: 50%;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: #eee;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
// tslint:disable:no-input-rename
|
||||
|
||||
import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges, OnInit, ViewEncapsulation, ContentChild, TemplateRef, ElementRef } from '@angular/core';
|
||||
import { DomSanitizer, SafeStyle } from '@angular/platform-browser';
|
||||
|
||||
|
||||
export const COLORS = { default: { text: '#222', bg: '#ddd' }, hover: { text: '#fff', bg: '#0078D4' } }
|
||||
|
||||
@Component({
|
||||
selector: 'app-triangle',
|
||||
templateUrl: './triangle.component.html',
|
||||
|
@ -8,46 +13,37 @@ import { DomSanitizer, SafeStyle } from '@angular/platform-browser';
|
|||
})
|
||||
export class TriangleComponent implements OnInit {
|
||||
|
||||
@ContentChild(TemplateRef) dotTemplate;
|
||||
@Input() triangleSize; // In pixels, largest triangle size (height and width).
|
||||
@Input() dotSize = 35; // In pixels
|
||||
|
||||
seconds = 0;
|
||||
start;
|
||||
elapsed;
|
||||
start: number;
|
||||
scale = 3;
|
||||
dots;
|
||||
isActive;
|
||||
dots: Array<SierpinskiTriangleDot>;
|
||||
isActive: boolean;
|
||||
interval: NodeJS.Timer;
|
||||
|
||||
callback;
|
||||
interval;
|
||||
|
||||
constructor() {
|
||||
// Force stop after limited time during development.
|
||||
setTimeout(() => {
|
||||
this.stop();
|
||||
}, 10000);
|
||||
}
|
||||
constructor(private el: ElementRef) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.dots = (new SierpinskiTriangle({x: 0, y: 0, s: 1000}, 25)).getDots();
|
||||
// setTimeout(() => this.stop(), 10000); // Force stop after limited time during development.
|
||||
|
||||
if (!this.triangleSize) {
|
||||
// Calculate size based on this element's size.
|
||||
this.triangleSize = Math.min(this.el.nativeElement.offsetHeight * 1.3, this.el.nativeElement.offsetWidth * 0.7);
|
||||
}
|
||||
this.dots = (new SierpinskiTriangle({x: 0, y: 0, size: this.triangleSize}, this.dotSize)).getDots();
|
||||
this.begin();
|
||||
}
|
||||
|
||||
update(elapsed) {
|
||||
const t = (elapsed / 1000) % 10;
|
||||
const scale = 1 + (t > 5 ? 10 - t : t) / 10;
|
||||
this.scale = scale / 2.1;
|
||||
}
|
||||
|
||||
begin() {
|
||||
this.isActive = true;
|
||||
|
||||
this.interval = setInterval(() => {
|
||||
this.seconds = (this.seconds % 10) + 1;
|
||||
}, 1000);
|
||||
|
||||
this.interval = setInterval(() => this.updateSeconds(), 1000);
|
||||
this.start = new Date().getTime();
|
||||
|
||||
const callback = () => {
|
||||
this.update(Date.now() - this.start);
|
||||
this.updateScale();
|
||||
if (this.isActive) {
|
||||
requestAnimationFrame(callback);
|
||||
}
|
||||
|
@ -61,11 +57,17 @@ export class TriangleComponent implements OnInit {
|
|||
}
|
||||
|
||||
toggle() {
|
||||
if (this.isActive) {
|
||||
this.stop();
|
||||
} else {
|
||||
this.begin();
|
||||
}
|
||||
this.isActive ? this.stop() : this.begin();
|
||||
}
|
||||
|
||||
updateSeconds() {
|
||||
this.seconds = (this.seconds % 10) + 1;
|
||||
}
|
||||
|
||||
updateScale(elapsed = Date.now() - this.start) {
|
||||
const t = (elapsed / 1000) % 10;
|
||||
const scale = 1 + (t > 5 ? 10 - t : t) / 10;
|
||||
this.scale = scale / 2.1;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -75,20 +77,20 @@ class SierpinskiTriangle {
|
|||
triangles: Array<SierpinskiTriangle> | any = [];
|
||||
dot: SierpinskiTriangleDot;
|
||||
|
||||
constructor({ x, y, s }, targetSize) {
|
||||
if (s <= targetSize) {
|
||||
constructor({ x, y, size }, targetSize) {
|
||||
if (size <= targetSize) {
|
||||
this.dot = new SierpinskiTriangleDot(
|
||||
x - (targetSize / 2),
|
||||
y - (targetSize / 2),
|
||||
targetSize
|
||||
);
|
||||
} else {
|
||||
const newSize = s / 2;
|
||||
s /= 2;
|
||||
const newSize = size / 2;
|
||||
size /= 2;
|
||||
this.triangles = [
|
||||
new SierpinskiTriangle({x, y: y - (s / 2), s}, targetSize),
|
||||
new SierpinskiTriangle({x: x - s, y: y + (s / 2), s}, targetSize),
|
||||
new SierpinskiTriangle({x: x + s, y: y + (s / 2), s}, targetSize)
|
||||
new SierpinskiTriangle({x, y: y - (size / 2), size}, targetSize),
|
||||
new SierpinskiTriangle({x: x - size, y: y + (size / 2), size}, targetSize),
|
||||
new SierpinskiTriangle({x: x + size, y: y + (size / 2), size}, targetSize)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -101,6 +103,10 @@ class SierpinskiTriangle {
|
|||
|
||||
class SierpinskiTriangleDot {
|
||||
|
||||
hover = false;
|
||||
|
||||
constructor(private _x, private _y, private _size) { }
|
||||
|
||||
get x() {
|
||||
return this._x + 'px';
|
||||
}
|
||||
|
@ -113,6 +119,16 @@ class SierpinskiTriangleDot {
|
|||
return this._size * 0.9 + 'px';
|
||||
}
|
||||
|
||||
constructor(private _x, private _y, private _size) { }
|
||||
get color() {
|
||||
return this.hover ? COLORS.hover.text : COLORS.default.text;
|
||||
}
|
||||
|
||||
get backgroundColor() {
|
||||
return this.hover ? COLORS.hover.bg : COLORS.default.bg;
|
||||
}
|
||||
|
||||
get textOverride() {
|
||||
return this.hover ? '-' : '';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,19 @@
|
|||
<h1>Angular Perf Demo</h1>
|
||||
<h3>Pure Angular View</h3>
|
||||
|
||||
<app-triangle></app-triangle>
|
||||
<app-triangle>
|
||||
<ng-template let-text="text" let-dot="dot">
|
||||
<app-dot
|
||||
[size]="dot.size"
|
||||
[x]="dot.x"
|
||||
[y]="dot.y"
|
||||
[color]="dot.color"
|
||||
[textOverride]="dot.textOverride"
|
||||
[backgroundColor]="dot.backgroundColor"
|
||||
(onMouseEnter)="dot.hover = true"
|
||||
(onMouseLeave)="dot.hover = false"
|
||||
>
|
||||
{{ text }}
|
||||
</app-dot>
|
||||
</ng-template>
|
||||
</app-triangle>
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
:host {
|
||||
display: block;
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
app-triangle {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,23 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { AngularReactFabricModule } from '@angular-react/fabric';
|
||||
|
||||
import { AngularPerfComponent } from './angular-perf/angular-perf.component';
|
||||
import { MixedPerfComponent } from './mixed-perf/mixed-perf.component';
|
||||
import { FabricComponent } from './fabric/fabric.component';
|
||||
import { MaterialComponent } from './material/material.component';
|
||||
import { LandingComponent } from './landing/landing.component';
|
||||
import { ComponentsModule } from '../components/components.module';
|
||||
import { AngularReactFabricModule } from '@angular-react/fabric';
|
||||
import { ReactComponentsModule } from '../react-components/react-components.module';
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
ComponentsModule,
|
||||
AngularReactFabricModule,
|
||||
ReactComponentsModule,
|
||||
],
|
||||
declarations: [AngularPerfComponent, MixedPerfComponent, FabricComponent, MaterialComponent, LandingComponent]
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<h1>Microsoft Fabric Components</h1>
|
||||
|
||||
<!-- <ul>
|
||||
<ul>
|
||||
<li>
|
||||
<fabric-button label="Toggle Disabled" (onClick)="toggle()"></fabric-button>
|
||||
<fabric-button [disabled]="disabled" (onClick)="click()" label="Primary Button{{ disabled ? ' (0)' : ' (2)' }}"></fabric-button>
|
||||
|
@ -11,25 +11,12 @@
|
|||
</li>
|
||||
<li>
|
||||
<fabric-button label="Toggle Dialog" (onClick)="toggleDialog()"></fabric-button>
|
||||
<fabric-dialog [hidden]="dialogHidden" (onDismiss)="toggleDialog()"></fabric-dialog>
|
||||
<fabric-dialog [hidden]="dialogHidden" (onDismiss)="toggleDialog()" key="d2">
|
||||
{{ sampleContent2 }} {{ sampleContent3 }}
|
||||
<fabric-dialog-footer key="d3">
|
||||
<fabric-button (onClick)="clickSave()" label='Save' style="margin-right:10px;"></fabric-button>
|
||||
<fabric-button (onClick)="toggleDialog()" label='Cancel'></fabric-button>
|
||||
</fabric-dialog-footer>
|
||||
</fabric-dialog>
|
||||
</li>
|
||||
</ul> -->
|
||||
|
||||
<button (click)="toggleDialog()">Toggle Dialog</button>
|
||||
<button (click)="click()">Increment</button>
|
||||
|
||||
<!-- <fabric-dialog [hidden]="dialogHidden" (onDismiss)="toggleDialog()"></fabric-dialog> -->
|
||||
|
||||
|
||||
<!-- <fabric-dialog [hidden]="dialogHidden" (onDismiss)="toggleDialog()">
|
||||
{{ sampleContent2 }}
|
||||
</fabric-dialog> -->
|
||||
|
||||
|
||||
|
||||
<fabric-dialog [hidden]="dialogHidden" (onDismiss)="toggleDialog()">
|
||||
<fabric-dialog-footer key="3">
|
||||
<fabric-button (onClick)="click()" text='Save'></fabric-button>
|
||||
<fabric-button (onClick)="click()" text='Cancel'></fabric-button>
|
||||
</fabric-dialog-footer>
|
||||
</fabric-dialog>
|
||||
</ul>
|
||||
|
|
|
@ -12,16 +12,21 @@ export class FabricComponent implements OnInit {
|
|||
sampleContentCounter = 0;
|
||||
secondsCounter = 0;
|
||||
sampleContent2 = '0 Seconds Passed';
|
||||
sampleContent3 = '';
|
||||
|
||||
get sampleContent() {
|
||||
return `Button clicked ${this.sampleContentCounter} times.`;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
// setInterval(() => {
|
||||
// this.secondsCounter += 1;
|
||||
// this.sampleContent2 = `${this.secondsCounter} Seconds Passed`
|
||||
// }, 1000);
|
||||
const i = setInterval(() => {
|
||||
this.secondsCounter += 1;
|
||||
this.sampleContent2 = `${this.secondsCounter} Seconds Passed`
|
||||
}, 1000);
|
||||
|
||||
setTimeout(() => {
|
||||
clearInterval(i);
|
||||
}, 12000);
|
||||
}
|
||||
|
||||
ngOnInit() { }
|
||||
|
@ -32,10 +37,15 @@ export class FabricComponent implements OnInit {
|
|||
|
||||
toggleDialog() {
|
||||
this.dialogHidden = !this.dialogHidden;
|
||||
this.sampleContent3 = '';
|
||||
}
|
||||
|
||||
click() {
|
||||
this.sampleContentCounter += 1;
|
||||
}
|
||||
|
||||
clickSave() {
|
||||
this.sampleContent3 = 'Saved...';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,24 @@
|
|||
<h1>Mixed Perf Demo</h1>
|
||||
<h3>React leaf nodes rendered in an Angular View</h3>
|
||||
|
||||
<app-triangle></app-triangle>
|
||||
<header>
|
||||
<h1>Mixed Perf Demo</h1>
|
||||
<h3>React leaf nodes rendered in an Angular View</h3>
|
||||
<h4 *ngIf="projectAsAngular">Number as Angular projection</h4>
|
||||
<h4 *ngIf="!projectAsAngular">Number as React attribute</h4>
|
||||
<button (click)="toggle()">Toggle Projection</button>
|
||||
</header>
|
||||
<app-triangle>
|
||||
<ng-template let-text="text" let-dot="dot">
|
||||
<app-react-dot
|
||||
[size]="dot.size"
|
||||
[x]="dot.x"
|
||||
[y]="dot.y"
|
||||
[color]="dot.color"
|
||||
[textOverride]="dot.textOverride"
|
||||
[backgroundColor]="dot.backgroundColor"
|
||||
(onMouseEnter)="dot.hover = true"
|
||||
(onMouseLeave)="dot.hover = false"
|
||||
[text]="projectAsAngular ? '' : text"
|
||||
>
|
||||
{{ projectAsAngular ? dot.textOverride ? dot.textOverride : text : '' }}
|
||||
</app-react-dot>
|
||||
</ng-template>
|
||||
</app-triangle>
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
:host {
|
||||
display: block;
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
app-triangle {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-mixed-perf',
|
||||
templateUrl: './mixed-perf.component.html',
|
||||
styleUrls: ['./mixed-perf.component.scss']
|
||||
})
|
||||
export class MixedPerfComponent implements OnInit {
|
||||
export class MixedPerfComponent {
|
||||
|
||||
constructor() { }
|
||||
projectAsAngular = true;
|
||||
|
||||
ngOnInit() {
|
||||
toggle() {
|
||||
this.projectAsAngular = !this.projectAsAngular;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<ReactDot
|
||||
[dynamicStyle]="style"
|
||||
[text]="text"
|
||||
(onMouseEnter)="onMouseEnter($event)"
|
||||
(onMouseLeave)="onMouseLeave($event)"
|
||||
>
|
||||
<react-content>
|
||||
<ng-content></ng-content>
|
||||
</react-content>
|
||||
</ReactDot>
|
|
@ -0,0 +1,3 @@
|
|||
:host {
|
||||
display: block;
|
||||
}
|
|
@ -1,7 +1,4 @@
|
|||
/* tslint:disable:no-unused-variable */
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { DebugElement } from '@angular/core';
|
||||
|
||||
import { ReactDotComponent } from './react-dot.component';
|
||||
|
||||
|
|
|
@ -1,77 +1,93 @@
|
|||
import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core';
|
||||
// tslint:disable:no-input-rename
|
||||
// tslint:disable:no-output-rename
|
||||
import { Component, ChangeDetectionStrategy, Input, Output, EventEmitter, OnChanges } from '@angular/core';
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-react-dot',
|
||||
template: `
|
||||
<ReactDot [text]="hover ? '*' + text + '*' : text">
|
||||
</ReactDot>
|
||||
`,
|
||||
templateUrl: './react-dot.component.html',
|
||||
styleUrls: ['./react-dot.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
styles: [ 'react-renderer' ],
|
||||
})
|
||||
export class ReactDotComponent implements OnChanges {
|
||||
|
||||
@Input() x: number;
|
||||
@Input() y: number;
|
||||
@Input() size: number;
|
||||
@Input() text: string;
|
||||
style: ReactDotStyle;
|
||||
|
||||
hover = false;
|
||||
style: { [k: string]: any };
|
||||
bgColor: string;
|
||||
@Input() x: string;
|
||||
@Input() y: string;
|
||||
@Input() size: string;
|
||||
@Input('text') _text: string;
|
||||
@Input() color: string;
|
||||
@Input() backgroundColor: string;
|
||||
@Input() textOverride: string;
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
const shapeChanged = 'x' in changes || 'y' in changes || 'size' in changes;
|
||||
@Output('onMouseEnter') mouseEnter: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
|
||||
@Output('onMouseLeave') mouseLeave: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
|
||||
|
||||
if (shapeChanged) {
|
||||
this.updateStyle();
|
||||
}
|
||||
onMouseEnter = ev => this.mouseEnter.emit(ev as any);
|
||||
onMouseLeave = ev => this.mouseLeave.emit(ev as any);
|
||||
|
||||
get text() {
|
||||
return this.textOverride && this._text ? this.textOverride : this._text;
|
||||
}
|
||||
|
||||
enter() {
|
||||
this.hover = true;
|
||||
this.bgColor = '#ff0';
|
||||
}
|
||||
|
||||
leave() {
|
||||
this.hover = false;
|
||||
this.bgColor = undefined;
|
||||
}
|
||||
|
||||
private updateStyle() {
|
||||
const s = this.size * 1.3;
|
||||
ngOnChanges() {
|
||||
this.style = {
|
||||
width: s + 'px',
|
||||
height: s + 'px',
|
||||
left: (this.x) + 'px',
|
||||
top: (this.y) + 'px',
|
||||
borderRadius: (s / 2) + 'px',
|
||||
lineHeight: (s) + 'px',
|
||||
width: this.size,
|
||||
lineHeight: this.size,
|
||||
height: this.size,
|
||||
left: this.x,
|
||||
top: this.y,
|
||||
color: this.color,
|
||||
backgroundColor: this.backgroundColor,
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface ReactDotStyle {
|
||||
display?: string,
|
||||
position?: string,
|
||||
textAlign?: string,
|
||||
borderRadius?: string,
|
||||
cursor?: string,
|
||||
|
||||
width?: string,
|
||||
lineHeight?: string,
|
||||
height?: string,
|
||||
left?: string,
|
||||
top?: string,
|
||||
color?: string,
|
||||
backgroundColor?: string,
|
||||
}
|
||||
|
||||
interface ReactDotProps {
|
||||
style: ReactDotStyle
|
||||
onMouseEnter?: (ev) => void,
|
||||
onMouseLeave?: (ev) => void,
|
||||
}
|
||||
|
||||
export class ReactDot extends React.Component {
|
||||
|
||||
private divStyle = {
|
||||
position: 'absolute',
|
||||
background: '#61dafb',
|
||||
font: 'normal 15px sans-serif',
|
||||
textAlign: 'center',
|
||||
cursor: 'pointer'
|
||||
}
|
||||
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
private propsOut: ReactDotProps = {
|
||||
style: {
|
||||
display: 'block',
|
||||
position: 'absolute',
|
||||
textAlign: 'center',
|
||||
borderRadius: '50%',
|
||||
cursor: 'pointer',
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return React.createElement('div', { style: this.divStyle }, [this.props['text']]);
|
||||
this.propsOut.style = { ...this.propsOut.style, ...this.props['dynamicStyle'] };
|
||||
this.propsOut.onMouseEnter = this.props['onMouseEnter'];
|
||||
this.propsOut.onMouseLeave = this.props['onMouseLeave'];
|
||||
|
||||
return React.createElement('div', this.propsOut, [this.props['text'], ...this.props.children as any]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1 +1,5 @@
|
|||
/* You can add global styles to this file, and also import other style files */
|
||||
html, body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../dist/out-tsc/apps/demo",
|
||||
"outDir": "../../../dist/out-tsc/apps/demo-from-packages",
|
||||
"module": "es2015"
|
||||
},
|
||||
"include": [
|
||||
|
@ -11,4 +11,4 @@
|
|||
"exclude": [
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,14 +1,17 @@
|
|||
import * as React from 'react';
|
||||
import ReactDOM = require('react-dom');
|
||||
import { CHILD_TO_APPEND_PROP } from '@angular-react/core/src/renderer/react-node';
|
||||
|
||||
|
||||
const DEBUG = false;
|
||||
export const CHILDREN_TO_APPEND_PROP = 'children-to-append';
|
||||
|
||||
export class ReactContent extends React.Component {
|
||||
|
||||
componentDidMount() {
|
||||
const element = ReactDOM.findDOMNode(this);
|
||||
console.log('component mounted, node:', element, 'props:', this.props);
|
||||
if (this.props['childtoappend']) {
|
||||
element.appendChild(this.props[CHILD_TO_APPEND_PROP]);
|
||||
if (this.props[CHILDREN_TO_APPEND_PROP]) {
|
||||
if (DEBUG) { console.warn('ReactContent Component > componentDidMount > childrenToAppend:', this.props[CHILDREN_TO_APPEND_PROP]); }
|
||||
this.props[CHILDREN_TO_APPEND_PROP].map(child => element.appendChild(child));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@ import { Renderer2 } from '@angular/core';
|
|||
|
||||
import { ReactComponentClass, getComponentClass } from "./registry";
|
||||
import { AngularReactRendererFactory } from "./renderer";
|
||||
import { CHILDREN_TO_APPEND_PROP } from './react-content';
|
||||
|
||||
|
||||
const DEBUG = true;
|
||||
export const CHILD_TO_APPEND_PROP = 'child-to-append';
|
||||
const DEBUG = false;
|
||||
|
||||
export function isReactNode(node: any): node is ReactNode {
|
||||
return (<ReactNode>node).setRenderPendingCallback !== undefined;
|
||||
|
@ -24,7 +24,7 @@ export class ReactNode {
|
|||
private typeIsReactElementClass;
|
||||
private children: Array<ReactNode> = [];
|
||||
private typeName: string;
|
||||
private childToAppend: HTMLElement;
|
||||
private childrenToAppend: Array<HTMLElement> = [];
|
||||
|
||||
private renderedDomElement: HTMLElement;
|
||||
get domElement() {
|
||||
|
@ -150,7 +150,7 @@ export class ReactNode {
|
|||
return this.text;
|
||||
}
|
||||
|
||||
this.props[CHILD_TO_APPEND_PROP] = this.childToAppend;
|
||||
this.props[CHILDREN_TO_APPEND_PROP] = this.childrenToAppend;
|
||||
|
||||
if (DEBUG) { console.warn('ReactNode > renderRecursive > type:', this.toString(), 'props:', this.props, 'children:', children); }
|
||||
return React.createElement(this.type, this.props, children);
|
||||
|
@ -159,7 +159,7 @@ export class ReactNode {
|
|||
// This is called by Angular core when projected content is being added.
|
||||
appendChild(projectedContent: HTMLElement) {
|
||||
if (DEBUG) { console.error('ReactNode > appendChild > node:', this.toString(), 'projectedContent:', projectedContent.toString().trim()); }
|
||||
this.childToAppend = projectedContent;
|
||||
this.childrenToAppend.push(projectedContent);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
|
|
|
@ -19,7 +19,7 @@ import { ReactComponentClass, getComponentClass } from './registry';
|
|||
import { ReactNode, isReactNode } from './react-node';
|
||||
|
||||
|
||||
const DEBUG = true;
|
||||
const DEBUG = false;
|
||||
|
||||
@Injectable()
|
||||
export class AngularReactRendererFactory extends ɵDomRendererFactory2 {
|
||||
|
|
|
@ -25,7 +25,6 @@ import { DialogType, DialogFooter } from 'office-ui-fabric-react/lib/components/
|
|||
[modalProps]="modalProps"
|
||||
>
|
||||
<ReactContent><ng-content></ng-content></ReactContent>
|
||||
<div>test123</div>
|
||||
</Dialog>
|
||||
`,
|
||||
styles: ['react-renderer'],
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
// Protractor configuration file, see link for more information
|
||||
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
||||
|
||||
|
@ -27,4 +28,4 @@ exports.config = {
|
|||
});
|
||||
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
||||
}
|
||||
};
|
||||
};
|
|
@ -13,10 +13,7 @@
|
|||
"**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"**/e2e/*.ts",
|
||||
"**/*.e2e-spec.ts",
|
||||
"**/*.po.ts",
|
||||
"node_modules",
|
||||
"tmp"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -90,13 +90,17 @@
|
|||
"use-pipe-transform-interface": true,
|
||||
"component-class-suffix": true,
|
||||
"directive-class-suffix": true,
|
||||
|
||||
"nx-enforce-module-boundaries": [
|
||||
true,
|
||||
{
|
||||
"allow": [],
|
||||
"depConstraints": [
|
||||
{ "sourceTag": "*", "onlyDependOnLibsWithTags": ["*"] }
|
||||
{
|
||||
"sourceTag": "*",
|
||||
"onlyDependOnLibsWithTags": [
|
||||
"*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
Загрузка…
Ссылка в новой задаче