A bunch of updates to the demo site including PERF triangle for Angular.

This commit is contained in:
Ben Feely 2018-04-04 18:29:47 -07:00
Родитель ae743b4040
Коммит 22384d3325
42 изменённых файлов: 814 добавлений и 87 удалений

Просмотреть файл

@ -1,33 +1,7 @@
{
"$schema": "./node_modules/@nrwl/schematics/src/schema.json",
"project": {
"name": "angular-react",
"npmScope": "angular-react",
"latestMigration": "20180328-add-nx-lint"
},
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
}
},
"lint": [
{
"project": "./tsconfig.spec.json",
"exclude": "**/node_modules/**"
},
{
"project": "apps/demo/src/tsconfig.app.json",
"exclude": "**/node_modules/**"
},
{
"project": "apps/demo/e2e/tsconfig.e2e.json",
"exclude": "**/node_modules/**"
}
],
"test": {
"karma": {
"config": "./karma.conf.js"
}
"name": "angular-react"
},
"apps": [
{
@ -53,8 +27,7 @@
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
},
"tags": []
}
},
{
"name": "demo-from-packages",
@ -79,42 +52,63 @@
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
},
"tags": []
}
},
{
"name": "core",
"root": "libs/core/src",
"test": "../../../test.js",
"appRoot": "",
"tags": []
"root": "libs/core/src",
"test": "../../../test.js"
},
{
"name": "fabric",
"root": "libs/fabric/src",
"test": "../../../test.js",
"appRoot": "",
"tags": []
"root": "libs/fabric/src",
"test": "../../../test.js"
},
{
"name": "material",
"root": "libs/material/src",
"test": "../../../test.js",
"appRoot": "",
"tags": []
"root": "libs/material/src",
"test": "../../../test.js"
},
{
"name": "$workspaceRoot",
"root": ".",
"appRoot": ""
"appRoot": "",
"root": "."
}
],
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
}
},
"lint": [
{
"project": "./tsconfig.spec.json",
"exclude": "**/node_modules/**"
},
{
"project": "apps/demo/src/tsconfig.app.json",
"exclude": "**/node_modules/**"
},
{
"project": "apps/demo/e2e/tsconfig.e2e.json",
"exclude": "**/node_modules/**"
}
],
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "scss",
"component": {
},
"schematics": {
"collection": "@nrwl/schematics"
},
"styleExt": "css",
"component": {}
}
},
"warnings": {
"typescriptMismatch": false

Просмотреть файл

@ -0,0 +1,33 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LandingComponent } from './containers/landing/landing.component';
import { AngularPerfComponent } from './containers/angular-perf/angular-perf.component';
import { MixedPerfComponent } from './containers/mixed-perf/mixed-perf.component';
import { FabricComponent } from './containers/fabric/fabric.component';
import { MaterialComponent } from './containers/material/material.component';
const routes: Routes = [
{ path: 'landing', redirectTo: '' },
{ path: '', component: LandingComponent },
{ path: 'perf', children: [
{ path: 'angular', component: AngularPerfComponent },
{ path: 'mixed', component: MixedPerfComponent },
] },
{ path: 'components', children: [
{ path: 'fabric', component: FabricComponent },
{ path: 'material', component: MaterialComponent },
] },
];
@NgModule({
imports: [
RouterModule.forRoot(routes)
],
exports: [
RouterModule
],
declarations: []
})
export class AppRoutingModule { }

Просмотреть файл

Просмотреть файл

@ -1,24 +1,7 @@
<h1>Angular React Demo</h1>
<a routerLink="landing">Landing</a>
<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>
<!-- <button (click)="toggle()">Toggle</button>
<ul>
<li>
<fabric-button label="Toggle Disabled" (onClick)="toggle()"></fabric-button>
</li>
<li>
<fabric-button [disabled]="disabled" (onClick)="click()" label="Primary Button{{ disabled ? ' (0)' : ' (2)' }}"></fabric-button>
</li>
<li>
<fabric-button [primary]="false" (onClick)="click()" label="Secondary Button"></fabric-button>
</li>
</ul> -->
<fabric-button label="Toggle Dialog" (onClick)="toggleDialog()"></fabric-button>
<fabric-dialog [hidden]="dialogHidden" (onDismiss)="toggleDialog()"></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> -->
<router-outlet></router-outlet>

Просмотреть файл

@ -0,0 +1,7 @@
:host {
display: block;
a {
margin-right: 10px;
}
}

Просмотреть файл

@ -4,27 +4,12 @@ import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
disabled = true;
dialogHidden = true;
constructor() { }
ngOnInit() {
}
ngOnInit() { }
toggle() {
this.disabled = !this.disabled;
}
toggleDialog() {
this.dialogHidden = !this.dialogHidden;
}
click() {
console.log('clicked');
}
}

Просмотреть файл

@ -2,9 +2,13 @@ import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { NxModule } from '@nrwl/nx';
import { AngularReactBrowserModule } from '@angular-react/core';
import { AngularReactBrowserModule, registerElement } from '@angular-react/core';
import { AngularReactFabricModule } from '@angular-react/fabric';
import { AppComponent } from './app.component';
import { ComponentsModule } from './components/components.module';
import { ReactComponentsModule } from './react-components/react-components.module';
import { AppRoutingModule } from './app-routing.module';
import { ContainersModule } from './containers/containers.module';
@NgModule({
@ -12,6 +16,11 @@ import { AppComponent } from './app.component';
AngularReactBrowserModule,
NxModule.forRoot(),
AngularReactFabricModule,
AppRoutingModule,
ContainersModule,
ComponentsModule,
ReactComponentsModule,
],
declarations: [AppComponent],
bootstrap: [AppComponent]

Просмотреть файл

@ -0,0 +1,20 @@
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DotComponent } from './dot/dot.component';
import { ReactComponentsModule } from '../react-components/react-components.module';
import { TriangleComponent } from './triangle/triangle.component';
import { AngularReactFabricModule } from '@angular-react/fabric';
const components = [
DotComponent,
TriangleComponent,
];
@NgModule({
imports: [CommonModule, AngularReactFabricModule, ReactComponentsModule],
declarations: components,
exports: components,
})
export class ComponentsModule { }

Просмотреть файл

@ -0,0 +1,12 @@
<div
[style.width]="size"
[style.line-height]="size"
[style.height]="size"
[style.left]="x"
[style.top]="y"
[class.hover]="hover"
(mouseenter)="onMouseEnter($event)"
(mouseleave)="onMouseLeave($event)"
>
{{ text }}
</div>

Просмотреть файл

@ -0,0 +1,14 @@
:host div {
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;
}

Просмотреть файл

@ -0,0 +1,28 @@
/* 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 { DotComponent } from './dot.component';
describe('DotComponent', () => {
let component: DotComponent;
let fixture: ComponentFixture<DotComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ DotComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DotComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

Просмотреть файл

@ -0,0 +1,26 @@
import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core';
@Component({
selector: 'app-dot',
templateUrl: './dot.component.html',
styleUrls: ['./dot.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DotComponent {
@Input() x: string;
@Input() y: string;
@Input() size: string;
@Input() text: string;
hover = false;
onMouseEnter(ev) {
this.hover = true;
}
onMouseLeave(ev) {
this.hover = false;
}
}

Просмотреть файл

@ -0,0 +1,11 @@
<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>
</div>

Просмотреть файл

@ -0,0 +1,13 @@
:host {
display: block;
.container {
position: absolute;
transform-origin: 0 0;
left: 50%;
top: 50%;
width: 10px;
height: 10px;
background: #eee;
}
}

Просмотреть файл

@ -0,0 +1,28 @@
/* 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 { TriangleComponent } from './triangle.component';
describe('TriangleComponent', () => {
let component: TriangleComponent;
let fixture: ComponentFixture<TriangleComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ TriangleComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TriangleComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

Просмотреть файл

@ -0,0 +1,113 @@
import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges, OnInit, ViewEncapsulation } from '@angular/core';
import { DomSanitizer, SafeStyle } from '@angular/platform-browser';
@Component({
selector: 'app-triangle',
templateUrl: './triangle.component.html',
styleUrls: ['./triangle.component.scss'],
})
export class TriangleComponent implements OnInit {
seconds = 0;
start;
elapsed;
scale = 3;
dots;
isActive;
callback;
interval;
constructor() { }
ngOnInit() {
this.dots = (new SierpinskiTriangle({x: 0, y: 0, s: 1000}, 25)).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.start = new Date().getTime();
const callback = () => {
this.update(Date.now() - this.start);
if (this.isActive) {
requestAnimationFrame(callback);
}
}
callback();
}
stop() {
this.isActive = false;
clearInterval(this.interval);
}
toggle() {
if (this.isActive) {
this.stop();
} else {
this.begin();
}
}
}
class SierpinskiTriangle {
triangles: Array<SierpinskiTriangle> | any = [];
dot: SierpinskiTriangleDot;
constructor({ x, y, s }, targetSize) {
if (s <= targetSize) {
this.dot = new SierpinskiTriangleDot(
x - (targetSize / 2),
y - (targetSize / 2),
targetSize
);
} else {
const newSize = s / 2;
s /= 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)
];
}
}
getDots() {
return this.triangles.reduce( (acc, t) => [...acc, ...t.getDots(), ...(t.dot || [])], []);
}
}
class SierpinskiTriangleDot {
get x() {
return this._x + 'px';
}
get y() {
return this._y + 'px';
}
get size() {
return this._size * 0.9 + 'px';
}
constructor(private _x, private _y, private _size) { }
}

Просмотреть файл

@ -0,0 +1,4 @@
<h1>Angular Perf Demo</h1>
<h3>Pure Angular View</h3>
<app-triangle></app-triangle>

Просмотреть файл

@ -0,0 +1,4 @@
:host {
display: block;
}

Просмотреть файл

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AngularPerfComponent } from './angular-perf.component';
describe('AngularPerfComponent', () => {
let component: AngularPerfComponent;
let fixture: ComponentFixture<AngularPerfComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AngularPerfComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AngularPerfComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

Просмотреть файл

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-angular-perf',
templateUrl: './angular-perf.component.html',
styleUrls: ['./angular-perf.component.scss']
})
export class AngularPerfComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}

Просмотреть файл

@ -0,0 +1,19 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
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';
@NgModule({
imports: [
CommonModule,
ComponentsModule,
AngularReactFabricModule,
],
declarations: [AngularPerfComponent, MixedPerfComponent, FabricComponent, MaterialComponent, LandingComponent]
})
export class ContainersModule { }

Просмотреть файл

@ -0,0 +1,25 @@
<h1>Microsoft Fabric Components</h1>
<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>
</li>
<li>
<fabric-button [primary]="false" (onClick)="click()" label="Secondary Button"></fabric-button>
<span class="button-height">{{ sampleContent }}</span>
</li>
<li>
<fabric-button label="Toggle Dialog" (onClick)="toggleDialog()"></fabric-button>
<fabric-dialog [hidden]="dialogHidden" (onDismiss)="toggleDialog()"></fabric-dialog>
</li>
</ul>
<!-- <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> -->

Просмотреть файл

@ -0,0 +1,22 @@
:host {
fabric-button {
margin-right: 20px;
}
ul {
list-style: none;
li {
margin-bottom: 10px;
span.button-height {
line-height: 30px;
}
}
}
}
:host {
display: block;
}

Просмотреть файл

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FabricComponent } from './fabric.component';
describe('FabricComponent', () => {
let component: FabricComponent;
let fixture: ComponentFixture<FabricComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ FabricComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(FabricComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

Просмотреть файл

@ -0,0 +1,34 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-fabric',
templateUrl: './fabric.component.html',
styleUrls: ['./fabric.component.scss']
})
export class FabricComponent implements OnInit {
disabled = true;
dialogHidden = true;
sampleContentCounter = 0;
get sampleContent() {
return `Button clicked ${this.sampleContentCounter} times.`;
}
constructor() { }
ngOnInit() { }
toggle() {
this.disabled = !this.disabled;
}
toggleDialog() {
this.dialogHidden = !this.dialogHidden;
}
click() {
this.sampleContentCounter += 1;
}
}

Просмотреть файл

@ -0,0 +1,3 @@
<p>
landing works!
</p>

Просмотреть файл

@ -0,0 +1,4 @@
:host {
display: block;
}

Просмотреть файл

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { LandingComponent } from './landing.component';
describe('LandingComponent', () => {
let component: LandingComponent;
let fixture: ComponentFixture<LandingComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ LandingComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LandingComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

Просмотреть файл

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-landing',
templateUrl: './landing.component.html',
styleUrls: ['./landing.component.scss']
})
export class LandingComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}

Просмотреть файл

@ -0,0 +1 @@
<h1>Google Material Components</h1>

Просмотреть файл

@ -0,0 +1,4 @@
:host {
display: block;
}

Просмотреть файл

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MaterialComponent } from './material.component';
describe('MaterialComponent', () => {
let component: MaterialComponent;
let fixture: ComponentFixture<MaterialComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MaterialComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MaterialComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

Просмотреть файл

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-material',
templateUrl: './material.component.html',
styleUrls: ['./material.component.scss']
})
export class MaterialComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}

Просмотреть файл

@ -0,0 +1,4 @@
<h1>Mixed Perf Demo</h1>
<h3>React leaf nodes rendered in an Angular View</h3>
<app-triangle></app-triangle>

Просмотреть файл

@ -0,0 +1,4 @@
:host {
display: block;
}

Просмотреть файл

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MixedPerfComponent } from './mixed-perf.component';
describe('MixedPerfComponent', () => {
let component: MixedPerfComponent;
let fixture: ComponentFixture<MixedPerfComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MixedPerfComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MixedPerfComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

Просмотреть файл

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-mixed-perf',
templateUrl: './mixed-perf.component.html',
styleUrls: ['./mixed-perf.component.scss']
})
export class MixedPerfComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}

Просмотреть файл

@ -0,0 +1,25 @@
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
import { CommonModule } from '@angular/common';
import { registerElement } from '@angular-react/core';
import { ReactDotComponent, ReactDot } from './react-dot/react-dot.component';
const components = [
ReactDotComponent,
];
@NgModule({
imports: [CommonModule],
declarations: components,
exports: components,
schemas: [NO_ERRORS_SCHEMA]
})
export class ReactComponentsModule {
constructor() {
// Add any React elements to the registry (used by the renderer).
registerElement('ReactDot', () => ReactDot);
}
}

Просмотреть файл

@ -0,0 +1,28 @@
/* 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';
describe('ReactDotComponent', () => {
let component: ReactDotComponent;
let fixture: ComponentFixture<ReactDotComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ReactDotComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ReactDotComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

Просмотреть файл

@ -0,0 +1,77 @@
import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } 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>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [ 'react-renderer' ],
})
export class ReactDotComponent implements OnChanges {
@Input() x: number;
@Input() y: number;
@Input() size: number;
@Input() text: string;
hover = false;
style: { [k: string]: any };
bgColor: string;
ngOnChanges(changes: SimpleChanges) {
const shapeChanged = 'x' in changes || 'y' in changes || 'size' in changes;
if (shapeChanged) {
this.updateStyle();
}
}
enter() {
this.hover = true;
this.bgColor = '#ff0';
}
leave() {
this.hover = false;
this.bgColor = undefined;
}
private updateStyle() {
const s = this.size * 1.3;
this.style = {
width: s + 'px',
height: s + 'px',
left: (this.x) + 'px',
top: (this.y) + 'px',
borderRadius: (s / 2) + 'px',
lineHeight: (s) + 'px',
};
}
}
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);
}
render() {
return React.createElement('div', { style: this.divStyle }, [this.props['text']]);
}
}

Просмотреть файл

@ -0,0 +1,4 @@
:host {
background: red;
display: inline-block;
}

Просмотреть файл

@ -18,7 +18,11 @@ import { IButtonProps, DefaultButton } from 'office-ui-fabric-react/lib/Button';
[text]="text"
(onClick)="onClick($event)"></DefaultButton>
`,
styles: ['react-renderer'],
styleUrls: ['./fabric-button.component.css'],
styles: [
'react-renderer',
':host { display: inline-block; background: red; }'
],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class FabricButtonComponent {