Skip to content

Commit

Permalink
feat: support style isolation (#166)
Browse files Browse the repository at this point in the history
* feat: support style isolation

* feat: support style isolation

* feat: support style isolation

* chore: fix error test

* test: add test about style isolation

* feat: style isolation

Co-authored-by: zhenshuaiwws <[email protected]>
  • Loading branch information
luxiaobei and zhenshuaiwws authored Dec 26, 2020
1 parent 71a331a commit 5a6d6e0
Show file tree
Hide file tree
Showing 39 changed files with 705 additions and 101 deletions.
21 changes: 12 additions & 9 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
}
},
"portal": {
"root": "",
"root": "examples/portal/src",
"sourceRoot": "examples/portal/src",
"projectType": "application",
"prefix": "app",
Expand All @@ -55,9 +55,10 @@
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "./extra-webpack.config.js",
"path": "examples/portal/src/extra-webpack.config.js",
"mergeStrategies": {
"externals": "replace"
"externals": "replace",
"module.rules": "append"
}
},
"baseHref": "/",
Expand All @@ -67,7 +68,7 @@
"polyfills": "examples/portal/src/polyfills.ts",
"tsConfig": "examples/portal/src/tsconfig.app.json",
"assets": ["examples/portal/src/favicon.ico", "examples/portal/src/assets"],
"styles": ["examples/portal/src/styles.scss"],
"styles": ["examples/portal/src/styles.scss", "examples/portal/src/reboot.scss"],
"extractCss": true,
"scripts": [],
"aot": true
Expand Down Expand Up @@ -152,7 +153,7 @@
"customWebpackConfig": {
"path": "./examples/app1/extra-webpack.config.js",
"mergeStrategies": {
"module.rules": "prepend"
"module.rules": "append"
},
"replaceDuplicatePlugins": true
},
Expand All @@ -164,7 +165,8 @@
"styles": ["examples/app1/src/styles.scss"],
"scripts": [],
"aot": true,
"vendorChunk": false
"vendorChunk": false,
"extractCss": true
},
"configurations": {
"production": {
Expand Down Expand Up @@ -246,7 +248,7 @@
"customWebpackConfig": {
"path": "./examples/app2/extra-webpack.config.js",
"mergeStrategies": {
"module.rules": "prepend"
"module.rules": "append"
},
"replaceDuplicatePlugins": true
},
Expand All @@ -255,10 +257,11 @@
"main": "examples/app2/src/main.ts",
"tsConfig": "examples/app2/tsconfig.app.json",
"assets": ["examples/app2/src/favicon.ico", "examples/app2/src/assets"],
"styles": ["examples/app2/src/styles.css"],
"styles": ["examples/app2/src/styles.scss"],
"scripts": [],
"vendorChunk": false,
"aot": true
"aot": true,
"extractCss": true
},
"configurations": {
"production": {
Expand Down
24 changes: 23 additions & 1 deletion examples/app1/extra-webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,30 @@
const WebpackAssetsManifest = require('webpack-assets-manifest');
const PrefixWrap = require('@worktile/planet-postcss-prefixwrap');

module.exports = {
optimization: {
runtimeChunk: false
},
plugins: [new WebpackAssetsManifest()]
plugins: [new WebpackAssetsManifest()],
module: {
rules: [
{
test: /\.scss$/,
use: [
{
loader: 'postcss-loader',
options: {
plugins: [
PrefixWrap('.app1', {
hasAttribute: 'planet-inline',
prefixRootTags: true
})
]
}
},
'sass-loader'
]
}
]
}
};
29 changes: 23 additions & 6 deletions examples/app1/src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,45 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { RouterModule, Route } from '@angular/router';
import { RouterModule } from '@angular/router';
import { NgxTethysModule } from 'ngx-tethys';
import { DashboardComponent } from './dashboard/dashboard.component';
import { routers } from './app.routing';
import { AppRootComponent, AppActualRootComponent } from './root/root.component';
import { DemoCommonModule } from '@demo/common';
import { DemoCommonModule, OVERLAY_PROVIDER } from '@demo/common';
import { NgxPlanetModule } from 'ngx-planet';
import { ProjectsComponent } from './projects/projects.component';
import { App1DetailComponent } from './detail/detail.component';
import { Overlay, OverlayModule } from '@angular/cdk/overlay';
import { FormsModule } from '@angular/forms';
import { AppOverlay } from './overlay';
import { ProjectsDialogComponent } from './projects/dialog/projects-dialog.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { SharedModule } from './shared.module';

@NgModule({
declarations: [AppRootComponent, AppActualRootComponent, DashboardComponent, ProjectsComponent],
declarations: [
AppRootComponent,
AppActualRootComponent,
DashboardComponent,
ProjectsComponent,
App1DetailComponent,
ProjectsDialogComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
RouterModule.forRoot(routers),
// UserModule,
NgxTethysModule,
FormsModule,
SharedModule,
DemoCommonModule,
NgxPlanetModule
NgxPlanetModule,
OverlayModule
],
providers: [],
entryComponents: [],
providers: [OVERLAY_PROVIDER, { provide: Overlay, useClass: AppOverlay }],
entryComponents: [App1DetailComponent, ProjectsDialogComponent],
bootstrap: [AppRootComponent]
})
export class AppModule {}
27 changes: 25 additions & 2 deletions examples/app1/src/app/dashboard/dashboard.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,40 @@
</section-card>

<section-card class="mt-4" title="Counter service, it will be cache in coexist mode">
<h5 class="red">count: {{ counter.count }}</h5>
<h5 class="same-name portal-special">count: {{ counter.count }}</h5>
<div class="btn-pair">
<button thyButton="primary-square" (click)="counter.increase()">Increase</button>
<button thyButton="outline-primary-square" (click)="counter.decrease()">Decrease</button>
</div>
</section-card>

<section-card class="mt-4" title="Open portal's detail">
<section-card class="mt-4" title="Open app1's detail">
<form class="mb-2" thyForm thyLayout="inline">
<thy-form-group thyLabelText="Size:">
<thy-custom-select thyPlaceHolder="选择弹框大小" name="size" [(ngModel)]="size" style="width:500px;">
<thy-option thyValue="sm" thyLabelText="" [thyShowOptionCustom]="true">
<span class="same-name"></span>
</thy-option>
<thy-option thyValue="md" thyLabelText="" [thyShowOptionCustom]="true">
<span class="same-name"></span>
</thy-option>
<thy-option thyValue="lg" thyLabelText="" [thyShowOptionCustom]="true">
<span class="same-name"></span>
</thy-option>
</thy-custom-select>
</thy-form-group>
</form>
<button thyButton="primary-square" (click)="openApp1Dialog()">Open app1's detail</button>
</section-card>

<section-card class="mt-4" title="Open portal's dialog">
<button thyButton="primary-square" (click)="openADetail()">Open portal's detail</button>
</section-card>

<section-card class="mt-4" title="Open app1's dialog has app2's component">
<button thyButton="primary-square" (click)="openApp2Dialog()">Open app1's dialog has app2's com</button>
</section-card>

<section-card class="mt-4" title="Render app2's component">
<div class="btn-pair">
<button thyButton="primary-square" (click)="openApp2Component()">Open App2 Projects</button>
Expand Down
18 changes: 17 additions & 1 deletion examples/app1/src/app/dashboard/dashboard.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { Router } from '@angular/router';
import { CounterService } from '../counter.service';
import { AppRootContext } from '@demo/common';
import { PlanetComponentRef, PlanetComponentLoader, PlanetPortalApplication, GlobalEventDispatcher } from 'ngx-planet';
import { ThyDialog } from 'ngx-tethys';
import { ThyDialog, ThyDialogSizes } from 'ngx-tethys';
import { App1DetailComponent } from '../detail/detail.component';
import { ProjectsDialogComponent } from '../projects/dialog/projects-dialog.component';

@Component({
selector: 'app-dashboard',
Expand All @@ -12,6 +14,8 @@ import { ThyDialog } from 'ngx-tethys';
export class DashboardComponent implements OnInit {
@ViewChild('container', { static: true }) containerElementRef: ElementRef<HTMLDivElement>;

public size: ThyDialogSizes = ThyDialogSizes.md;

private componentRef: PlanetComponentRef;

constructor(
Expand All @@ -30,6 +34,18 @@ export class DashboardComponent implements OnInit {
this.globalEventDispatcher.dispatch('openADetail');
}

openApp1Dialog() {
this.dialog.open(App1DetailComponent, {
size: this.size
});
}

openApp2Dialog() {
this.dialog.open(ProjectsDialogComponent, {
size: ThyDialogSizes.supperLg
});
}

openApp2Component() {
this.planetComponentLoader
.load('app2', 'project1', {
Expand Down
8 changes: 8 additions & 0 deletions examples/app1/src/app/detail/detail.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<thy-dialog-header thyTitle="a Detail from App1"> </thy-dialog-header>
<thy-dialog-body>
<span class="same-name">This is Micro Front-end application example.</span>
<div class="btn-pair mt-2">
<button thyButton="primary-square" (click)="ok()">Ok</button>
<button thyButton="link-secondary" (click)="close()">Cancel</button>
</div>
</thy-dialog-body>
18 changes: 18 additions & 0 deletions examples/app1/src/app/detail/detail.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Component } from '@angular/core';
import { ThyDialogRef } from 'ngx-tethys/dialog';

@Component({
selector: 'app-detail',
templateUrl: './detail.component.html'
})
export class App1DetailComponent {
constructor(private dialogRef: ThyDialogRef<App1DetailComponent>) {}

ok() {
this.dialogRef.close();
}

close() {
this.dialogRef.close();
}
}
65 changes: 65 additions & 0 deletions examples/app1/src/app/overlay.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Directionality } from '@angular/cdk/bidi';
import {
Overlay,
OverlayConfig,
OverlayContainer,
OverlayKeyboardDispatcher,
OverlayPositionBuilder,
OverlayRef,
ScrollStrategyOptions
} from '@angular/cdk/overlay';
import { DOCUMENT, Location } from '@angular/common';
import { ComponentFactoryResolver, Inject, Injectable, Injector, NgZone } from '@angular/core';
import { helpers } from 'ngx-tethys';

@Injectable()
export class AppOverlay extends Overlay {
constructor(
/** Scrolling strategies that can be used when creating an overlay. */
scrollStrategies: ScrollStrategyOptions,
_overlayContainer: OverlayContainer,
_componentFactoryResolver: ComponentFactoryResolver,
_positionBuilder: OverlayPositionBuilder,
_keyboardDispatcher: OverlayKeyboardDispatcher,
_injector: Injector,
_ngZone: NgZone,
@Inject(DOCUMENT) _document: any,
_directionality: Directionality,
_location: Location
) {
super(
scrollStrategies,
_overlayContainer,
_componentFactoryResolver,
_positionBuilder,
_keyboardDispatcher,
_injector,
_ngZone,
_document,
_directionality,
_location
);
}

private getOverlayPanelClasses(config: OverlayConfig) {
let classes = ['app1'];
if (config.panelClass) {
if (helpers.isArray(config.panelClass)) {
classes = classes.concat(config.panelClass);
} else {
classes.push(config.panelClass as string);
}
}
return classes;
}

create(config?: OverlayConfig): OverlayRef {
const overlayConfig: OverlayConfig = {
...config,
panelClass: this.getOverlayPanelClasses(config)
};
const overlayRef = super.create(overlayConfig);
overlayRef.addPanelClass(overlayConfig.panelClass);
return overlayRef;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<thy-dialog-header thyTitle="a Detail from App1"> </thy-dialog-header>
<thy-dialog-body>
<span class="same-name">this is a app2's component </span>
<thy-loading [thyDone]="loadingDone"></thy-loading>
<div #container></div>
</thy-dialog-body>
<thy-dialog-footer [thyDivided]="true">
<button thyButton="primary-square" (click)="ok()">Ok</button>
<button thyButton="link-secondary" (click)="close()">Cancel</button>
</thy-dialog-footer>
41 changes: 41 additions & 0 deletions examples/app1/src/app/projects/dialog/projects-dialog.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Component, ElementRef, EventEmitter, HostBinding, OnInit, ViewChild } from '@angular/core';
import { PlanetComponentLoader } from 'ngx-planet';
import { ThyDialogRef } from 'ngx-tethys';

@Component({
selector: 'app-projects-dialog',
templateUrl: `./projects-dialog.component.html`
})
export class ProjectsDialogComponent implements OnInit {
@HostBinding('class.thy-dialog-content') container = true;

@ViewChild('container', { static: true }) elementRef: ElementRef<HTMLDivElement>;

loadingDone = false;

constructor(
private planetComponentLoader: PlanetComponentLoader,
private dialogRef: ThyDialogRef<ProjectsDialogComponent>
) {}

ngOnInit() {
this.planetComponentLoader
.load<{ click: EventEmitter<any> }>('app2', 'project1', {
container: this.elementRef
})
.subscribe(componentRef => {
this.loadingDone = true;
componentRef.componentInstance.click.subscribe(() => {
console.log('project item clicked');
});
});
}

ok() {
this.dialogRef.close();
}

close() {
this.dialogRef.close();
}
}
Loading

0 comments on commit 5a6d6e0

Please sign in to comment.