-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Nebular cdk module, which is a wrapper over Angular cdk and provides some Nebular specific features, such as overrides of the overlay module. Closes #661, closes #660.
- Loading branch information
1 parent
22e39eb
commit b9283d3
Showing
23 changed files
with
875 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
src/framework/theme/components/cdk/adapter/adapter.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { NgModule } from '@angular/core'; | ||
import { OverlayContainer, ScrollDispatcher } from '@angular/cdk/overlay'; | ||
|
||
import { NbOverlayContainerAdapter } from './overlay-container-adapter'; | ||
import { NbScrollDispatcherAdapter } from './scroll-dispatcher-adapter'; | ||
import { NbViewportRulerAdapter } from './viewport-ruler-adapter'; | ||
|
||
|
||
@NgModule({ | ||
providers: [ | ||
NbViewportRulerAdapter, | ||
{ provide: OverlayContainer, useClass: NbOverlayContainerAdapter }, | ||
{ provide: ScrollDispatcher, useClass: NbScrollDispatcherAdapter }, | ||
], | ||
}) | ||
export class NbCdkAdapterModule { | ||
} |
15 changes: 15 additions & 0 deletions
15
src/framework/theme/components/cdk/adapter/overlay-container-adapter.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { Injectable } from '@angular/core'; | ||
|
||
import { NbOverlayContainer } from '../overlay/mapping'; | ||
|
||
|
||
@Injectable() | ||
export class NbOverlayContainerAdapter extends NbOverlayContainer { | ||
protected _createContainer(): void { | ||
const container = this._document.createElement('div'); | ||
|
||
container.classList.add('cdk-overlay-container'); | ||
this._document.querySelector('nb-layout').appendChild(container); | ||
this._containerElement = container; | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
src/framework/theme/components/cdk/adapter/scroll-dispatcher-adapter.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { Injectable, NgZone } from '@angular/core'; | ||
import { CdkScrollable, ScrollDispatcher } from '@angular/cdk/overlay'; | ||
import { Observable } from 'rxjs'; | ||
|
||
import { NbPlatform } from '../overlay/mapping'; | ||
import { NbLayoutScrollService } from '../../../services/scroll.service'; | ||
|
||
@Injectable() | ||
export class NbScrollDispatcherAdapter extends ScrollDispatcher { | ||
constructor(ngZone: NgZone, platform: NbPlatform, protected scrollService: NbLayoutScrollService) { | ||
super(ngZone, platform); | ||
} | ||
|
||
scrolled(auditTimeInMs?: number): Observable<CdkScrollable | void> { | ||
return this.scrollService.onScroll(); | ||
} | ||
} | ||
|
41 changes: 41 additions & 0 deletions
41
src/framework/theme/components/cdk/adapter/viewport-ruler-adapter.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { Injectable, NgZone } from '@angular/core'; | ||
import { ViewportRuler } from '@angular/cdk/overlay'; | ||
import { map } from 'rxjs/operators'; | ||
|
||
import { NbPlatform } from '../overlay/mapping'; | ||
import { NbLayoutRulerService } from '../../../services/ruler.service'; | ||
import { NbLayoutScrollService, NbScrollPosition } from '../../../services/scroll.service'; | ||
|
||
|
||
@Injectable() | ||
export class NbViewportRulerAdapter extends ViewportRuler { | ||
constructor(platform: NbPlatform, ngZone: NgZone, | ||
protected ruler: NbLayoutRulerService, | ||
protected scroll: NbLayoutScrollService) { | ||
super(platform, ngZone); | ||
} | ||
|
||
getViewportSize(): Readonly<{ width: number; height: number; }> { | ||
let res; | ||
/* | ||
* getDimensions call is really synchronous operation. | ||
* And we have to conform with the interface of the original service. | ||
* */ | ||
this.ruler.getDimensions() | ||
.pipe(map(dimensions => ({ width: dimensions.clientWidth, height: dimensions.clientHeight }))) | ||
.subscribe(rect => res = rect); | ||
return res; | ||
} | ||
|
||
getViewportScrollPosition(): { left: number; top: number } { | ||
let res; | ||
/* | ||
* getPosition call is really synchronous operation. | ||
* And we have to conform with the interface of the original service. | ||
* */ | ||
this.scroll.getPosition() | ||
.pipe(map((position: NbScrollPosition) => ({ top: position.y, left: position.x }))) | ||
.subscribe(position => res = position); | ||
return res; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './overlay/mapping'; | ||
export * from './overlay'; |
7 changes: 7 additions & 0 deletions
7
src/framework/theme/components/cdk/overlay/_overlay.theme.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
@import '~@angular/cdk/overlay-prebuilt.css'; | ||
|
||
@mixin nb-overlay-theme { | ||
.overlay-backdrop { | ||
background: nb-theme(overlay-backdrop-bg); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export * from './overlay.module'; | ||
export * from './overlay'; | ||
export * from './overlay-position'; | ||
export * from './overlay-container'; | ||
export * from './overlay-trigger'; | ||
export * from './mapping'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { Directive, Injectable, NgModule, TemplateRef, ViewContainerRef } from '@angular/core'; | ||
import { CdkPortal, ComponentPortal, Portal, PortalModule, TemplatePortal } from '@angular/cdk/portal'; | ||
import { | ||
ComponentType, | ||
ConnectedOverlayPositionChange, | ||
ConnectedPosition, | ||
ConnectionPositionPair, | ||
FlexibleConnectedPositionStrategy, | ||
GlobalPositionStrategy, | ||
Overlay, | ||
OverlayContainer, | ||
OverlayModule, | ||
OverlayPositionBuilder, | ||
OverlayRef, | ||
PositionStrategy, | ||
} from '@angular/cdk/overlay'; | ||
import { Platform } from '@angular/cdk/platform'; | ||
|
||
|
||
@Directive({ selector: '[nbPortal]' }) | ||
export class NbPortalDirective extends CdkPortal { | ||
} | ||
|
||
@Injectable() | ||
export class NbOverlayService extends Overlay { | ||
} | ||
|
||
@Injectable() | ||
export class NbPlatform extends Platform { | ||
} | ||
|
||
@Injectable() | ||
export class NbOverlayPositionBuilder extends OverlayPositionBuilder { | ||
} | ||
|
||
export class NbComponentPortal<T = any> extends ComponentPortal<T> { | ||
} | ||
|
||
export class NbTemplatePortal<T = any> extends TemplatePortal<T> { | ||
constructor(template: TemplateRef<T>, viewContainerRef?: ViewContainerRef, context?: T) { | ||
super(template, viewContainerRef, context); | ||
} | ||
} | ||
|
||
export class NbOverlayContainer extends OverlayContainer { | ||
} | ||
|
||
export class NbFlexibleConnectedPositionStrategy extends FlexibleConnectedPositionStrategy { | ||
} | ||
|
||
export type NbPortal<T = any> = Portal<T>; | ||
export type NbOverlayRef = OverlayRef; | ||
export type NbComponentType<T = any> = ComponentType<T>; | ||
export type NbGlobalPositionStrategy = GlobalPositionStrategy; | ||
export type NbPositionStrategy = PositionStrategy; | ||
export type NbConnectedPosition = ConnectedPosition; | ||
export type NbConnectedOverlayPositionChange = ConnectedOverlayPositionChange; | ||
export type NbConnectionPositionPair = ConnectionPositionPair; | ||
|
||
const CDK_MODULES = [OverlayModule, PortalModule]; | ||
|
||
const CDK_PROVIDERS = [ | ||
NbOverlayService, | ||
NbPlatform, | ||
NbOverlayPositionBuilder, | ||
]; | ||
|
||
/** | ||
* This module helps us to keep all angular/cdk deps inside our cdk module via providing aliases. | ||
* Approach will help us move cdk in separate npm package and refactor nebular/theme code. | ||
* */ | ||
@NgModule({ | ||
imports: [...CDK_MODULES], | ||
exports: [ | ||
...CDK_MODULES, | ||
NbPortalDirective, | ||
], | ||
declarations: [NbPortalDirective], | ||
providers: [...CDK_PROVIDERS], | ||
}) | ||
export class NbCdkMappingModule { | ||
} |
90 changes: 90 additions & 0 deletions
90
src/framework/theme/components/cdk/overlay/overlay-container.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import { ChangeDetectorRef, Component, HostBinding, Input, TemplateRef, Type, ViewChild } from '@angular/core'; | ||
import { NgComponentOutlet } from '@angular/common'; | ||
|
||
import { NbPosition } from './overlay-position'; | ||
|
||
export abstract class NbPositionedContainer { | ||
@Input() position: NbPosition; | ||
|
||
@HostBinding('class.nb-overlay-top') | ||
get top(): boolean { | ||
return this.position === NbPosition.TOP | ||
} | ||
|
||
@HostBinding('class.nb-overlay-right') | ||
get right(): boolean { | ||
return this.position === NbPosition.RIGHT | ||
} | ||
|
||
@HostBinding('class.nb-overlay-bottom') | ||
get bottom(): boolean { | ||
return this.position === NbPosition.BOTTOM | ||
} | ||
|
||
@HostBinding('class.nb-overlay-left') | ||
get left(): boolean { | ||
return this.position === NbPosition.LEFT | ||
} | ||
} | ||
|
||
@Component({ | ||
selector: 'nb-overlay-container', | ||
template: ` | ||
<ng-container *ngIf="isTemplate"> | ||
<ng-container *ngTemplateOutlet="content; context: context"></ng-container> | ||
</ng-container> | ||
<ng-container *ngIf="isComponent" [ngComponentOutlet]="content"></ng-container> | ||
<ng-container *ngIf="isPrimitive"> | ||
<div class="primitive-overlay">{{content}}</div> | ||
</ng-container> | ||
`, | ||
}) | ||
export class NbOverlayContainerComponent { | ||
@Input() | ||
content: any; | ||
|
||
@Input() | ||
context: Object; | ||
|
||
constructor(private cd: ChangeDetectorRef) { | ||
} | ||
|
||
@ViewChild(NgComponentOutlet) | ||
set componentOutlet(el) { | ||
if (this.isComponent) { | ||
Object.assign(el._componentRef.instance, this.context); | ||
/** | ||
* Change detection has to be performed here, because another way applied context | ||
* will be rendered on the next change detection loop and | ||
* we'll have incorrect positioning. Because rendered component may change its size | ||
* based on the context. | ||
* */ | ||
this.cd.detectChanges(); | ||
} | ||
} | ||
|
||
/** | ||
* Check that content is a TemplateRef. | ||
* | ||
* @return boolean | ||
* */ | ||
get isTemplate(): boolean { | ||
return this.content instanceof TemplateRef; | ||
} | ||
|
||
/** | ||
* Check that content is an angular component. | ||
* | ||
* @return boolean | ||
* */ | ||
get isComponent(): boolean { | ||
return this.content instanceof Type; | ||
} | ||
|
||
/** | ||
* Check that if content is not a TemplateRef or an angular component it means a primitive. | ||
* */ | ||
get isPrimitive(): boolean { | ||
return !this.isTemplate && !this.isComponent; | ||
} | ||
} |
Oops, something went wrong.