🅰️
Angular CDK Overlay でポップアップ Directive を実装する
だいぶ昔の記事で Angular CDK の Overlay モジュールの使い方を解説しました[1][2][3]。
今回は標準機能では実装できない簡易ポップアップを表示する Directive を実装してみるメモです。
環境
Angular CLI: 12.1.0
Node: 14.17.1
Package Manager: npm 6.14.10
OS: win32 x64
Angular: 12.1.0
... animations, cdk, cli, common, compiler, compiler-cli, core
... forms, material, platform-browser, platform-browser-dynamic
... router
Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1201.0
@angular-devkit/build-angular 12.1.0
@angular-devkit/core 12.1.0
@angular-devkit/schematics 12.1.0
@schematics/angular 12.1.0
rxjs 6.6.7
typescript 4.3.4
実装内容
今回の実装では Overlay モジュールの CdkConnectedOverlay
をマルッとコピペし、 FlexibleConnectedPositionStrategy
に関する箇所を GlobalPositionStrategy
に書き換えていきます。主には PositionStrategy に対する設定を行う _updatePositionStrategy
の中身を書き換えることと、 offsetX
などのプロパティの削除と追加になります。
元の CdkConnectedOverlay
:
コピペで作り替えた AppGlobalOverlay
:
例えば _updatePositionStrategy
はこのように変更しています。
// Before
private _updatePositionStrategy(positionStrategy: FlexibleConnectedPositionStrategy) {
const positions: ConnectedPosition[] = this.positions.map(currentPosition => ({
originX: currentPosition.originX,
originY: currentPosition.originY,
overlayX: currentPosition.overlayX,
overlayY: currentPosition.overlayY,
offsetX: currentPosition.offsetX || this.offsetX,
offsetY: currentPosition.offsetY || this.offsetY,
panelClass: currentPosition.panelClass || undefined,
}));
return positionStrategy
.setOrigin(this.origin.elementRef)
.withPositions(positions)
.withFlexibleDimensions(this.flexibleDimensions)
.withPush(this.push)
.withGrowAfterOpen(this.growAfterOpen)
.withViewportMargin(this.viewportMargin)
.withLockedPosition(this.lockPosition)
.withTransformOriginOn(this.transformOriginSelector);
}
// After
private _updatePositionStrategy(positionStrategy: GlobalPositionStrategy) {
if (this.centerVertical === true) {
positionStrategy = positionStrategy.centerVertically(this.centerVerticalOffset);
}
if (this.centerHorizontal === true) {
positionStrategy = positionStrategy.centerHorizontally(this.centerHorizontalOffset);
}
if (this.top != null) {
positionStrategy = positionStrategy.top(this.top);
}
if (this.bottom != null) {
positionStrategy = positionStrategy.bottom(this.bottom);
}
if (this.left != null) {
positionStrategy = positionStrategy.left(this.left);
}
if (this.right != null) {
positionStrategy = positionStrategy.right(this.right);
}
return positionStrategy;
}
使い方
基本的に CdkConnectedOverlay
と同一です。この実装で、ボタンを押すとカードのポップアップが出たり消えたりするようになります。
<button (click)="showPopup = !showPopup">Toggle popup</button>
<ng-template
appGlobalOverlay
[appGlobalOverlayOpen]="showPopup"
[appGlobalOverlayWidth]="'200px'"
[appGlobalOverlayHeight]="'100px'"
[appGlobalOverlayCenterVertical]="true"
[appGlobalOverlayCenterHorizontal]="true"
>
<mat-card>
<mat-card-title>ほげー</mat-card-title>
<mat-card-content>ふがー</mat-card-content>
</mat-card>
</ng-template>
Discussion