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
:
https://github.com/angular/components/blob/12.1.0/src/cdk/overlay/overlay-directives.ts
コピペで作り替えた AppGlobalOverlay
:
https://github.com/noxi515/angular-sample-global-overlay-directive/blob/master/src/app/global-overlay/global-overlay.directive.ts
例えば _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>