Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(popover, tooltip): add shown state api #1998

Merged
merged 20 commits into from
Oct 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { NbDynamicOverlay } from './dynamic-overlay';
import { NbOverlayContent } from '../overlay-service';
import { NbDynamicOverlayChange, NbDynamicOverlayHandler } from './dynamic-overlay-handler';
import { NbTrigger, NbTriggerStrategy, NbTriggerStrategyBuilderService } from '../overlay-trigger';
import { NbOverlayConfig } from '@nebular/theme/components/cdk/overlay/mapping';

@Component({ template: '' })
export class NbDynamicOverlayMockComponent implements NbRenderableContainer {
Expand All @@ -43,18 +44,21 @@ export class NbMockDynamicOverlay {
_context: Object = {};
_content: NbOverlayContent;
_positionStrategy: NbAdjustableConnectedPositionStrategy;
_overlayConfig: NbOverlayConfig;

constructor() {}

create(componentType: Type<NbRenderableContainer>,
content: NbOverlayContent,
context: Object,
positionStrategy: NbAdjustableConnectedPositionStrategy) {
positionStrategy: NbAdjustableConnectedPositionStrategy,
overlayConfig: NbOverlayConfig) {

this.setContext(context);
this.setContent(content);
this.setComponent(componentType);
this.setPositionStrategy(positionStrategy);
this.setOverlayConfig(overlayConfig);

return this;
}
Expand All @@ -71,6 +75,10 @@ export class NbMockDynamicOverlay {
this._componentType = componentType;
}

setOverlayConfig(overlayConfig: NbOverlayConfig) {
this._overlayConfig = overlayConfig;
}

setContentAndContext(content: NbOverlayContent, context: Object) {
this._content = content;
this._context = context;
Expand Down Expand Up @@ -516,4 +524,15 @@ describe('dynamic-overlay-handler', () => {
expect(positionBuilder._position).toBe(NbPosition.LEFT);
expect(positionBuilder._adjustment).toBe(NbAdjustment.HORIZONTAL);
});

it('should set and update overlay config', () => {
let overlayConfig: NbOverlayConfig = { panelClass: 'custom-class' };

let dynamic = configure().overlayConfig(overlayConfig).build();
expect(dynamic._overlayConfig).toEqual(jasmine.objectContaining(overlayConfig));

overlayConfig = { panelClass: 'other-custom-class' };
dynamic = configure().overlayConfig(overlayConfig).rebuild();
expect(dynamic._overlayConfig).toEqual(jasmine.objectContaining(overlayConfig));
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import { NbRenderableContainer } from '../overlay-container';
import { NbOverlayContent } from '../overlay-service';
import { NbDynamicOverlay } from './dynamic-overlay';
import { NbOverlayConfig } from '../mapping';

export class NbDynamicOverlayChange extends SimpleChange {

Expand All @@ -33,6 +34,7 @@ export class NbDynamicOverlayHandler {
protected _position: NbPosition = NbPosition.TOP;
protected _adjustment: NbAdjustment = NbAdjustment.NOOP;
protected _offset: number = 15;
protected _overlayConfig: NbOverlayConfig = {};

protected dynamicOverlay: NbDynamicOverlay;
protected triggerStrategy: NbTriggerStrategy;
Expand Down Expand Up @@ -94,6 +96,12 @@ export class NbDynamicOverlayHandler {
return this;
}

overlayConfig(overlayConfig: NbOverlayConfig) {
this.changes.overlayConfig = new NbDynamicOverlayChange(this._overlayConfig, overlayConfig);
this._overlayConfig = overlayConfig;
return this;
}

build() {
if (!this._componentType || !this._host) {
throw Error(`NbDynamicOverlayHandler: at least 'componentType' and 'host' should be
Expand All @@ -104,6 +112,7 @@ export class NbDynamicOverlayHandler {
this._content,
this._context,
this.createPositionStrategy(),
this._overlayConfig,
);

this.connect();
Expand Down Expand Up @@ -139,6 +148,10 @@ export class NbDynamicOverlayHandler {
this.dynamicOverlay.setComponent(this._componentType);
}

if (this.isOverlayConfigUpdateRequired()) {
this.dynamicOverlay.setOverlayConfig(this._overlayConfig);
}

this.clearChanges();
return this.dynamicOverlay;
}
Expand Down Expand Up @@ -203,6 +216,10 @@ export class NbDynamicOverlayHandler {
return this.isComponentTypeUpdated();
}

private isOverlayConfigUpdateRequired(): boolean {
return this.isOverlayConfigUpdated();
}

protected isComponentTypeUpdated(): boolean {
return this.changes.componentType && this.changes.componentType.isChanged();
}
Expand Down Expand Up @@ -235,6 +252,10 @@ export class NbDynamicOverlayHandler {
return this.changes.offset && this.changes.offset.isChanged();
}

protected isOverlayConfigUpdated(): boolean {
return this.changes.overlayConfig && this.changes.overlayConfig.isChanged();
}

protected clearChanges() {
this.changes = {};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,16 @@ describe('dynamic-overlay', () => {
expect(instance.content).toBe(newContent);
});

it('should set overlay config', () => {
const overlayConfig: NbOverlayConfig = { panelClass: 'additional-overlay-class' };
const createOverlaySpy = spyOn(overlayService, 'create').and.callThrough();

dynamicOverlay.setOverlayConfig(overlayConfig);
dynamicOverlay.show();

expect(createOverlaySpy).toHaveBeenCalledWith(jasmine.objectContaining(overlayConfig));
});

it('should return container', () => {
dynamicOverlay.show();
expect(dynamicOverlay.getContainer()).toBe(container as any);
Expand Down Expand Up @@ -319,29 +329,25 @@ describe('dynamic-overlay', () => {
});

it('should set component', () => {
const detachSpy = spyOn(ref, 'detach').and.callThrough();
const disposeSpy = spyOn(ref, 'dispose').and.callThrough();
const attachSpy = spyOn(ref, 'attach').and.callThrough();
const hasAttacheSpy = spyOn(ref, 'hasAttached');

dynamicOverlay.setComponent(NbDynamicOverlayMock2Component);

expect(detachSpy).toHaveBeenCalledTimes(0);
expect(disposeSpy).toHaveBeenCalledTimes(0);
expect(attachSpy).toHaveBeenCalledTimes(0);

dynamicOverlay.show();
hasAttacheSpy.and.returnValue(true);

expect(ref.portal.component).toBe(NbDynamicOverlayMock2Component);
expect(detachSpy).toHaveBeenCalledTimes(0);
expect(disposeSpy).toHaveBeenCalledTimes(0);
expect(attachSpy).toHaveBeenCalledTimes(1);

dynamicOverlay.setComponent(NbDynamicOverlayMockComponent);

expect(ref.portal.component).toBe(NbDynamicOverlayMockComponent);
expect(detachSpy).toHaveBeenCalledTimes(1);
expect(disposeSpy).toHaveBeenCalledTimes(1);
expect(attachSpy).toHaveBeenCalledTimes(2);

Expand All @@ -350,7 +356,6 @@ describe('dynamic-overlay', () => {

dynamicOverlay.setComponent(NbDynamicOverlayMock2Component);

expect(detachSpy).toHaveBeenCalledTimes(3);
expect(disposeSpy).toHaveBeenCalledTimes(2);
expect(attachSpy).toHaveBeenCalledTimes(2);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ComponentFactoryResolver, ComponentRef, Injectable, NgZone, Type } from '@angular/core';
import { filter, takeUntil, takeWhile } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { filter, takeUntil, takeWhile, distinctUntilChanged } from 'rxjs/operators';
import { Subject, BehaviorSubject, Observable } from 'rxjs';

import {
NbAdjustableConnectedPositionStrategy,
Expand All @@ -9,7 +9,7 @@ import {

import { NbRenderableContainer } from '../overlay-container';
import { createContainer, NbOverlayContent, NbOverlayService, patch } from '../overlay-service';
import { NbOverlayRef, NbOverlayContainer } from '../mapping';
import { NbOverlayRef, NbOverlayContainer, NbOverlayConfig } from '../mapping';

export interface NbDynamicOverlayController {
show();
Expand All @@ -27,14 +27,20 @@ export class NbDynamicOverlay {
protected context: Object = {};
protected content: NbOverlayContent;
protected positionStrategy: NbAdjustableConnectedPositionStrategy;
protected overlayConfig: NbOverlayConfig = {};

protected positionStrategyChange$ = new Subject();
protected isShown$ = new BehaviorSubject<boolean>(false);
protected alive = true;

get isAttached(): boolean {
return this.ref && this.ref.hasAttached();
}

get isShown(): Observable<boolean> {
return this.isShown$.pipe(distinctUntilChanged());
}

constructor(
protected overlay: NbOverlayService,
protected componentFactoryResolver: ComponentFactoryResolver,
Expand All @@ -45,11 +51,13 @@ export class NbDynamicOverlay {
create(componentType: Type<NbRenderableContainer>,
content: NbOverlayContent,
context: Object,
positionStrategy: NbAdjustableConnectedPositionStrategy) {
positionStrategy: NbAdjustableConnectedPositionStrategy,
overlayConfig: NbOverlayConfig = {}) {

this.setContentAndContext(content, context);
this.setComponent(componentType);
this.setPositionStrategy(positionStrategy);
this.setOverlayConfig(overlayConfig);

return this;
}
Expand Down Expand Up @@ -82,11 +90,10 @@ export class NbDynamicOverlay {
this.componentType = componentType;

// in case the component is shown we recreate it and show it back
if (this.ref && this.isAttached) {
this.dispose();
const wasAttached = this.isAttached;
this.disposeOverlayRef();
if (wasAttached) {
this.show();
} else if (this.ref && !this.isAttached) {
this.dispose();
}
}

Expand All @@ -108,6 +115,16 @@ export class NbDynamicOverlay {
}
}

setOverlayConfig(overlayConfig: NbOverlayConfig) {
this.overlayConfig = overlayConfig;

const wasAttached = this.isAttached;
this.disposeOverlayRef();
if (wasAttached) {
this.show();
}
}

show() {
if (!this.ref) {
this.createOverlay();
Expand All @@ -120,6 +137,8 @@ export class NbDynamicOverlay {
this.disposeOverlayRef();
return this.show();
}

this.isShown$.next(true);
}

hide() {
Expand All @@ -129,6 +148,8 @@ export class NbDynamicOverlay {

this.ref.detach();
this.container = null;

this.isShown$.next(false);
}

toggle() {
Expand All @@ -143,6 +164,8 @@ export class NbDynamicOverlay {
this.alive = false;
this.hide();
this.disposeOverlayRef();
this.isShown$.complete();
this.positionStrategyChange$.complete();
}

getContainer() {
Expand All @@ -153,6 +176,7 @@ export class NbDynamicOverlay {
this.ref = this.overlay.create({
positionStrategy: this.positionStrategy,
scrollStrategy: this.overlay.scrollStrategies.reposition(),
...this.overlayConfig,
});
this.updatePositionWhenStable();
}
Expand Down
Loading