diff --git a/src/framework/theme/components/context-menu/context-menu.component.ts b/src/framework/theme/components/context-menu/context-menu.component.ts
index c3d9f603ac..5c04559257 100644
--- a/src/framework/theme/components/context-menu/context-menu.component.ts
+++ b/src/framework/theme/components/context-menu/context-menu.component.ts
@@ -7,7 +7,7 @@
import { Component, Input } from '@angular/core';
import { NbMenuItem } from '../../components/menu/menu.service';
-import { NbPositionedContainer } from '../cdk';
+import { NbPositionedContainer, NbRenderableContainer } from '../cdk';
/**
* Context menu component used as content within NbContextMenuDirective.
@@ -23,10 +23,21 @@ import { NbPositionedContainer } from '../cdk';
styleUrls: ['./context-menu.component.scss'],
template: `
-
+
`,
})
-export class NbContextMenuComponent extends NbPositionedContainer {
+export class NbContextMenuComponent extends NbPositionedContainer implements NbRenderableContainer {
+
@Input() items: NbMenuItem[] = [];
@Input() tag: string;
+
+ @Input()
+ context: { items: NbMenuItem[], tag?: string } = { items: [] };
+
+
+ /**
+ * The method is empty since we don't need to do anything additionally
+ * render is handled by change detection
+ */
+ renderContent() {}
}
diff --git a/src/framework/theme/components/context-menu/context-menu.directive.ts b/src/framework/theme/components/context-menu/context-menu.directive.ts
index 762727db4f..0c617760b9 100644
--- a/src/framework/theme/components/context-menu/context-menu.directive.ts
+++ b/src/framework/theme/components/context-menu/context-menu.directive.ts
@@ -6,32 +6,28 @@
import {
AfterViewInit,
- ComponentFactoryResolver,
ComponentRef,
Directive,
ElementRef,
- Inject,
Input,
+ OnChanges,
OnDestroy,
+ OnInit,
} from '@angular/core';
import { filter, takeWhile } from 'rxjs/operators';
import {
- createContainer,
NbAdjustableConnectedPositionStrategy,
NbAdjustment,
+ NbDynamicOverlay,
+ NbDynamicOverlayController,
+ NbDynamicOverlayHandler,
NbOverlayRef,
- NbOverlayService,
NbPosition,
- NbPositionBuilderService,
NbTrigger,
- NbTriggerStrategy,
- NbTriggerStrategyBuilderService,
- patch,
} from '../cdk';
import { NbContextMenuComponent } from './context-menu.component';
import { NbMenuItem, NbMenuService } from '../menu/menu.service';
-import { NB_DOCUMENT } from '../../theme.options';
/**
* Full featured context menu directive.
@@ -106,8 +102,11 @@ import { NB_DOCUMENT } from '../../theme.options';
*
* @stacked-example(Manual Control, context-menu/context-menu-noop.component)
* */
-@Directive({ selector: '[nbContextMenu]' })
-export class NbContextMenuDirective implements AfterViewInit, OnDestroy {
+@Directive({
+ selector: '[nbContextMenu]',
+ providers: [NbDynamicOverlayHandler, NbDynamicOverlay],
+})
+export class NbContextMenuDirective implements NbDynamicOverlayController, OnChanges, AfterViewInit, OnDestroy, OnInit {
/**
* Position will be calculated relatively host element based on the position.
@@ -134,9 +133,9 @@ export class NbContextMenuDirective implements AfterViewInit, OnDestroy {
* Basic menu items, will be passed to the internal NbMenuComponent.
* */
@Input('nbContextMenu')
- set setItems(items: NbMenuItem[]) {
+ set items(items: NbMenuItem[]) {
this.validateItems(items);
- this.items = items;
+ this._items = items;
};
/**
@@ -150,96 +149,62 @@ export class NbContextMenuDirective implements AfterViewInit, OnDestroy {
protected container: ComponentRef;
protected positionStrategy: NbAdjustableConnectedPositionStrategy;
protected alive: boolean = true;
- private items: NbMenuItem[] = [];
+ private _items: NbMenuItem[] = [];
- constructor(@Inject(NB_DOCUMENT) protected document,
+ private dynamicOverlay: NbDynamicOverlay;
+
+ constructor(private hostRef: ElementRef,
private menuService: NbMenuService,
- private hostRef: ElementRef,
- private positionBuilder: NbPositionBuilderService,
- private triggerStrategyBuilder: NbTriggerStrategyBuilderService,
- private overlay: NbOverlayService,
- private componentFactoryResolver: ComponentFactoryResolver) {
+ private dynamicOverlayHandler: NbDynamicOverlayHandler) {
+ }
+
+ ngOnInit() {
+ this.dynamicOverlayHandler
+ .host(this.hostRef)
+ .componentType(NbContextMenuComponent);
+ }
+
+ ngOnChanges() {
+ this.rebuild();
}
ngAfterViewInit() {
- this.subscribeOnTriggers();
+ this.dynamicOverlay = this.configureDynamicOverlay()
+ .build();
this.subscribeOnItemClick();
- this.subscribeOnPositionChange();
}
- ngOnDestroy() {
- this.alive = false;
- this.hide();
- if (this.ref) {
- this.ref.dispose();
- }
+ rebuild() {
+ this.dynamicOverlay = this.configureDynamicOverlay()
+ .rebuild();
}
show() {
- if (!this.ref) {
- this.createOverlay();
- }
-
- this.openContextMenu();
+ this.dynamicOverlay.show();
}
hide() {
- if (this.ref) {
- this.ref.detach();
- }
-
- this.container = null;
+ this.dynamicOverlay.hide();
}
toggle() {
- if (this.ref && this.ref.hasAttached()) {
- this.hide();
- } else {
- this.show();
- }
- }
-
- protected createOverlay() {
- this.ref = this.overlay.create({
- positionStrategy: this.positionStrategy,
- scrollStrategy: this.overlay.scrollStrategies.reposition(),
- });
+ this.dynamicOverlay.toggle();
}
- protected openContextMenu() {
- this.container = createContainer(this.ref, NbContextMenuComponent, {
- position: this.position,
- items: this.items,
- tag: this.tag,
- }, this.componentFactoryResolver);
+ ngOnDestroy() {
+ this.dynamicOverlayHandler.destroy();
}
- protected createPositionStrategy(): NbAdjustableConnectedPositionStrategy {
- return this.positionBuilder
- .connectedTo(this.hostRef)
+ protected configureDynamicOverlay() {
+ return this.dynamicOverlayHandler
.position(this.position)
- .adjustment(this.adjustment);
- }
-
- protected createTriggerStrategy(): NbTriggerStrategy {
- return this.triggerStrategyBuilder
.trigger(this.trigger)
- .host(this.hostRef.nativeElement)
- .container(() => this.container)
- .build();
- }
-
- protected subscribeOnPositionChange() {
- this.positionStrategy = this.createPositionStrategy();
- this.positionStrategy.positionChange
- .pipe(takeWhile(() => this.alive))
- .subscribe((position: NbPosition) => patch(this.container, { position }));
- }
-
- protected subscribeOnTriggers() {
- const triggerStrategy = this.createTriggerStrategy();
- triggerStrategy.show$.pipe(takeWhile(() => this.alive)).subscribe(() => this.show());
- triggerStrategy.hide$.pipe(takeWhile(() => this.alive)).subscribe(() => this.hide());
+ .adjustment(this.adjustment)
+ .context({
+ position: this.position,
+ items: this._items,
+ tag: this.tag,
+ });
}
/*
diff --git a/src/framework/theme/components/context-menu/context-menu.spec.ts b/src/framework/theme/components/context-menu/context-menu.spec.ts
index e7f9a9b4b3..243c32c9ba 100644
--- a/src/framework/theme/components/context-menu/context-menu.spec.ts
+++ b/src/framework/theme/components/context-menu/context-menu.spec.ts
@@ -1,69 +1,111 @@
-import { Component, ComponentRef, ElementRef, Inject, Injectable, Input, NgModule, ViewChild } from '@angular/core';
-import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
-import { RouterTestingModule } from '@angular/router/testing';
+import { Component, ElementRef, Input, NgModule, Type, ViewChild } from '@angular/core';
+import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
-
-import { of as observableOf, Subject } from 'rxjs';
+import { RouterTestingModule } from '@angular/router/testing';
import { NbThemeModule } from '../../theme.module';
import { NbLayoutModule } from '../layout/layout.module';
import {
NbAdjustment,
+ NbDynamicOverlayHandler,
+ NbOverlayContent,
NbPosition,
- NbPositionBuilderService,
+ NbRenderableContainer,
NbTrigger,
- NbTriggerStrategy,
- NbTriggerStrategyBuilderService,
} from '../cdk';
-import { NB_DOCUMENT } from '../../theme.options';
-import { NbContextMenuDirective } from './context-menu.directive';
import { NbMenuModule } from '../menu/menu.module';
+import { NbContextMenuDirective } from './context-menu.directive';
+import { NbContextMenuComponent } from './context-menu.component';
import { NbContextMenuModule } from './context-menu.module';
-
@Component({
- selector: 'nb-context-menu-test',
+ selector: 'nb-context-menu-default-test',
template: `
-
+
`,
})
-export class NbContextMenuTestComponent {
- @Input() trigger: NbTrigger = NbTrigger.CLICK;
+export class NbContextMenuDefaultTestComponent {
@ViewChild('button') button: ElementRef;
@ViewChild(NbContextMenuDirective) contextMenu: NbContextMenuDirective;
items = [{ title: 'User' }, { title: 'Log Out' }];
}
-@NgModule({
- imports: [
- RouterTestingModule.withRoutes([]),
- NoopAnimationsModule,
- NbThemeModule.forRoot(),
- NbLayoutModule,
- NbMenuModule.forRoot(),
- NbContextMenuModule,
- ],
- declarations: [
- NbContextMenuTestComponent,
- ],
+@Component({
+ selector: 'nb-context-menu-bindings-test',
+ template: `
+
+
+
+
+
+ `,
+})
+export class NbContextMenuBindingsTestComponent {
+ @ViewChild(NbContextMenuDirective) contextMenu: NbContextMenuDirective;
+ @ViewChild('button') button: ElementRef;
+ @Input() trigger = NbTrigger.CLICK;
+ @Input() position = NbPosition.TOP;
+ @Input() adjustment = NbAdjustment.CLOCKWISE;
+ @Input() tag = '';
+ @Input() items = [{ title: 'User' }, { title: 'Log Out' }];
+}
+
+@Component({
+ selector: 'nb-context-menu-instance-test',
+ template: `
+
+
+
+
+
+
+ Some Template
+ `,
})
-export class ContextMenuTestModule {
+export class NbContextMenuInstanceTestComponent {
+ @ViewChild(NbContextMenuDirective) contextMenu: NbContextMenuDirective;
+ @ViewChild('button') button: ElementRef;
+
+ items = [{ title: 'User' }, { title: 'Log Out' }];
}
-export class MockPositionBuilder {
- positionChange = new Subject();
- _connectedTo: ElementRef;
- _position: NbPosition;
- _adjustment: NbAdjustment;
+const dynamicOverlay = {
+ show() {},
+ hide() {},
+ toggle() {},
+ destroy() {},
+};
+
+export class NbDynamicOverlayHandlerMock {
+ _componentType: Type;
+ _host: ElementRef;
+ _context: Object = {};
+ _content: NbOverlayContent;
+ _trigger: NbTrigger = NbTrigger.NOOP;
+ _position: NbPosition = NbPosition.TOP;
+ _adjustment: NbAdjustment = NbAdjustment.NOOP;
+ _offset: number;
+
+ constructor() {
+ }
+
+ host(host: ElementRef) {
+ this._host = host;
+ return this;
+ }
- connectedTo(connectedTo: ElementRef) {
- this._connectedTo = connectedTo;
+ trigger(trigger: NbTrigger) {
+ this._trigger = trigger;
return this;
}
@@ -77,158 +119,330 @@ export class MockPositionBuilder {
return this;
}
- offset() {
+ componentType(componentType: Type) {
+ this._componentType = componentType;
return this;
- };
-
- attach() {
- };
-
- apply() {
- };
-
- detach() {
- };
+ }
- dispose() {
- };
-}
+ content(content: NbOverlayContent) {
+ this._content = content;
+ return this;
+ }
-@Injectable()
-export class MockTriggerStrategyBuilder {
+ context(context: {}) {
+ this._context = context;
+ return this;
+ }
- _host: HTMLElement;
- _container: () => ComponentRef;
- _trigger: NbTrigger;
+ offset(offset: number) {
+ this._offset = offset;
+ return this;
+ }
- constructor(@Inject(NB_DOCUMENT) public _document: Document) {
+ build() {
+ return dynamicOverlay;
}
- trigger(trigger: NbTrigger): this {
- this._trigger = trigger;
- return this;
+ rebuild() {
+ return dynamicOverlay;
}
- host(host: HTMLElement): this {
- this._host = host;
- return this;
+ connect() {
}
- container(container: () => ComponentRef): this {
- this._container = container;
- return this;
+ disconnect() {
}
- build(): NbTriggerStrategy {
- return {
- show$: observableOf(null),
- hide$: observableOf(null),
- } as NbTriggerStrategy;
+ destroy() {
}
}
-describe('Directive: NbContextMenuDirective', () => {
- beforeEach(() => {
- TestBed.configureTestingModule({ imports: [ContextMenuTestModule] });
- });
+const TEST_COMPONENTS = [
+ NbContextMenuDefaultTestComponent,
+ NbContextMenuBindingsTestComponent,
+ NbContextMenuInstanceTestComponent,
+];
- let fixture: ComponentFixture;
+@NgModule({
+ imports: [NbLayoutModule, NbContextMenuModule],
+ exports: [...TEST_COMPONENTS],
+ declarations: [...TEST_COMPONENTS],
+})
+class ContextMenuTestModule { }
- beforeEach(() => {
- fixture = TestBed.createComponent(NbContextMenuTestComponent);
- fixture.detectChanges();
- });
+describe('Directive: NbContextMenuDirective', () => {
- afterEach(() => {
- fixture.destroy();
- });
+ const overlayHandler = new NbDynamicOverlayHandlerMock();
+
+ beforeEach(async(() => {
+ TestBed.resetTestingModule();
+ TestBed.configureTestingModule({
+ imports: [
+ NoopAnimationsModule,
+ RouterTestingModule.withRoutes([]),
+ NbThemeModule.forRoot(),
+ NbMenuModule.forRoot(),
+ ContextMenuTestModule,
+ ],
+ });
+ }));
- it('should render context menu', () => {
- fixture.componentInstance.contextMenu.show();
- fixture.detectChanges();
+ describe('smoke ', () => {
- const menu = fixture.nativeElement.querySelector('nb-context-menu nb-menu');
- expect(menu).toBeTruthy();
- });
+ let fixture: ComponentFixture;
- it('should hide', fakeAsync(() => {
- let menu;
- fixture.componentInstance.contextMenu.show();
- fixture.detectChanges();
+ afterEach(() => {
+ fixture.destroy();
+ });
- menu = fixture.nativeElement.querySelector('nb-context-menu nb-menu');
- expect(menu).toBeTruthy();
- fixture.componentInstance.contextMenu.hide();
- fixture.detectChanges();
+ it('should render string', () => {
+ fixture = TestBed.createComponent(NbContextMenuDefaultTestComponent);
+ fixture.detectChanges();
+ fixture.componentInstance.contextMenu.show();
+ fixture.detectChanges();
- tick(); // we need this tick for animations
- menu = fixture.nativeElement.querySelector('nb-context-menu nb-menu');
- expect(menu).toBeFalsy();
- }));
+ const textContainer = fixture.nativeElement.querySelector('nb-menu');
+ expect(textContainer.textContent).toContain('Log Out');
+ });
- it('should toogle', fakeAsync(() => {
- let menu;
+ it('should hide', () => fakeAsync(() => {
+ fixture = TestBed.createComponent(NbContextMenuDefaultTestComponent);
+ fixture.detectChanges();
+ fixture.componentInstance.contextMenu.show();
+ fixture.detectChanges();
- fixture.componentInstance.contextMenu.show();
- fixture.detectChanges();
- menu = fixture.nativeElement.querySelector('nb-context-menu nb-menu');
- expect(menu).toBeTruthy();
- fixture.componentInstance.contextMenu.toggle();
- fixture.detectChanges();
+ const textContainer = fixture.nativeElement.querySelector('nb-menu');
+ expect(textContainer.textContent).toContain('Logout');
+ fixture.componentInstance.contextMenu.hide();
+ fixture.detectChanges();
- tick(); // we need this tick for animations
- const tooltip = fixture.nativeElement.querySelector('nb-context-menu');
- expect(tooltip).toBeNull();
+ tick(); // we need this tick for animations
+ const contextMenu = fixture.nativeElement.querySelector('nb-menu');
+ expect(contextMenu).toBeNull();
+ }));
- fixture.componentInstance.contextMenu.toggle();
- fixture.detectChanges();
- tick();
+ it('should render different items', () => {
+ fixture = TestBed.createComponent(NbContextMenuDefaultTestComponent);
+ fixture.detectChanges();
- menu = fixture.nativeElement.querySelector('nb-context-menu nb-menu');
- expect(menu).toBeTruthy();
- }));
+ fixture.componentInstance.contextMenu.show();
+ fixture.detectChanges();
- it('should build position strategy', () => {
- const mockPositionBuilder = new MockPositionBuilder();
- TestBed.resetTestingModule();
- TestBed.configureTestingModule({
- imports: [ContextMenuTestModule],
- providers: [{ provide: NbPositionBuilderService, useValue: mockPositionBuilder }],
+ fixture.componentInstance.items = [ { title: 'Hello' } ];
+ fixture.detectChanges();
+ const textContainer = fixture.nativeElement.querySelector('nb-menu');
+ expect(textContainer.textContent).toContain('Hello');
});
- fixture = TestBed.createComponent(NbContextMenuTestComponent);
- fixture.detectChanges();
- expect(mockPositionBuilder._connectedTo.nativeElement).toBe(fixture.componentInstance.button.nativeElement);
- expect(mockPositionBuilder._position).toBe(NbPosition.BOTTOM);
- expect(mockPositionBuilder._adjustment).toBe(NbAdjustment.CLOCKWISE);
});
- it('should build with default trigger strategy', () => {
- TestBed.resetTestingModule();
- const bed = TestBed.configureTestingModule({
- imports: [ContextMenuTestModule],
- providers: [{ provide: NbTriggerStrategyBuilderService, useClass: MockTriggerStrategyBuilder }],
+ describe('mocked services', () => {
+
+ beforeEach(async(() => {
+ TestBed.resetTestingModule();
+ TestBed.configureTestingModule({
+ imports: [
+ RouterTestingModule.withRoutes([]),
+ NbThemeModule.forRoot(),
+ NbMenuModule.forRoot(),
+ ContextMenuTestModule,
+ ],
+ })
+ .overrideComponent(NbContextMenuDirective, {
+ set: {
+ providers: [
+ { provide: NbDynamicOverlayHandler, useValue: overlayHandler },
+ ],
+ },
+ });
+ }));
+ describe('default context-menu', () => {
+
+ let fixture: ComponentFixture;
+
+ afterEach(() => {
+ fixture.destroy();
+ });
+
+ it('should build', () => {
+ const componentSpy = spyOn(overlayHandler, 'componentType').and.callThrough();
+ const hostSpy = spyOn(overlayHandler, 'host').and.callThrough();
+ const positionSpy = spyOn(overlayHandler, 'position').and.callThrough();
+ const triggerSpy = spyOn(overlayHandler, 'trigger').and.callThrough();
+ const adjustmentSpy = spyOn(overlayHandler, 'adjustment').and.callThrough();
+ const contentSpy = spyOn(overlayHandler, 'content').and.callThrough();
+ const contextSpy = spyOn(overlayHandler, 'context').and.callThrough();
+ const offsetSpy = spyOn(overlayHandler, 'offset').and.callThrough();
+ const buildSpy = spyOn(overlayHandler, 'build').and.callThrough();
+ const rebuildSpy = spyOn(overlayHandler, 'rebuild').and.callThrough();
+
+ fixture = TestBed.createComponent(NbContextMenuDefaultTestComponent);
+ fixture.detectChanges();
+
+ expect(componentSpy).toHaveBeenCalledTimes(1);
+ expect(componentSpy).toHaveBeenCalledWith(NbContextMenuComponent);
+ expect(hostSpy).toHaveBeenCalledWith(fixture.componentInstance.button);
+ expect(hostSpy).toHaveBeenCalledTimes(1);
+ expect(offsetSpy).toHaveBeenCalledTimes(0);
+ expect(positionSpy).toHaveBeenCalledTimes(2);
+ expect(positionSpy).toHaveBeenCalledWith(NbPosition.BOTTOM);
+ expect(triggerSpy).toHaveBeenCalledTimes(2);
+ expect(triggerSpy).toHaveBeenCalledWith(NbTrigger.CLICK);
+ expect(adjustmentSpy).toHaveBeenCalledTimes(2);
+ expect(adjustmentSpy).toHaveBeenCalledWith(NbAdjustment.CLOCKWISE);
+ expect(contentSpy).toHaveBeenCalledTimes(0);
+ expect(contextSpy).toHaveBeenCalledTimes(2);
+ expect(contextSpy).toHaveBeenCalledWith({
+ position: NbPosition.BOTTOM,
+ items: [{ title: 'User' }, { title: 'Log Out' }],
+ tag: undefined,
+ });
+ expect(buildSpy).toHaveBeenCalledTimes(1);
+ expect(rebuildSpy).toHaveBeenCalledTimes(1);
+ });
+
+ it('should show/hide/toggle', () => {
+ fixture = TestBed.createComponent(NbContextMenuDefaultTestComponent);
+ fixture.detectChanges();
+ const showSpy = spyOn(dynamicOverlay, 'show').and.callThrough();
+ const hideSpy = spyOn(dynamicOverlay, 'hide').and.callThrough();
+ const toggleSpy = spyOn(dynamicOverlay, 'toggle').and.callThrough();
+
+ fixture.componentInstance.contextMenu.show();
+ fixture.detectChanges();
+
+ expect(showSpy).toHaveBeenCalledTimes(1);
+ expect(hideSpy).toHaveBeenCalledTimes(0);
+ expect(toggleSpy).toHaveBeenCalledTimes(0);
+
+ fixture.componentInstance.contextMenu.hide();
+ fixture.detectChanges();
+
+ expect(showSpy).toHaveBeenCalledTimes(1);
+ expect(hideSpy).toHaveBeenCalledTimes(1);
+ expect(toggleSpy).toHaveBeenCalledTimes(0);
+
+
+ fixture.componentInstance.contextMenu.toggle();
+ fixture.detectChanges();
+
+ expect(showSpy).toHaveBeenCalledTimes(1);
+ expect(hideSpy).toHaveBeenCalledTimes(1);
+ expect(toggleSpy).toHaveBeenCalledTimes(1);
+ });
});
- const mockTriggerStrategy = bed.get(NbTriggerStrategyBuilderService);
- fixture = TestBed.createComponent(NbContextMenuTestComponent);
- fixture.detectChanges();
- expect(mockTriggerStrategy._trigger).toBe(NbTrigger.CLICK);
- });
-
- it('should build with custom trigger strategy', () => {
- TestBed.resetTestingModule();
- const bed = TestBed.configureTestingModule({
- imports: [ContextMenuTestModule],
- providers: [{ provide: NbTriggerStrategyBuilderService, useClass: MockTriggerStrategyBuilder }],
+ describe('binding contextMenu', () => {
+
+ let fixture: ComponentFixture;
+
+ afterEach(() => {
+ fixture.destroy();
+ });
+
+ it('should rebuild', () => {
+
+ const componentSpy = spyOn(overlayHandler, 'componentType').and.callThrough();
+ const hostSpy = spyOn(overlayHandler, 'host').and.callThrough();
+ const positionSpy = spyOn(overlayHandler, 'position').and.callThrough();
+ const triggerSpy = spyOn(overlayHandler, 'trigger').and.callThrough();
+ const adjustmentSpy = spyOn(overlayHandler, 'adjustment').and.callThrough();
+ const contentSpy = spyOn(overlayHandler, 'content').and.callThrough();
+ const contextSpy = spyOn(overlayHandler, 'context').and.callThrough();
+ const offsetSpy = spyOn(overlayHandler, 'offset').and.callThrough();
+ const buildSpy = spyOn(overlayHandler, 'build').and.callThrough();
+ const rebuildSpy = spyOn(overlayHandler, 'rebuild').and.callThrough();
+
+ fixture = TestBed.createComponent(NbContextMenuBindingsTestComponent);
+ fixture.detectChanges();
+
+ fixture.componentInstance.adjustment = NbAdjustment.HORIZONTAL;
+ fixture.componentInstance.trigger = NbTrigger.HOVER;
+ fixture.componentInstance.items = [{ title: 'New' }];
+ fixture.componentInstance.tag = 'new';
+ fixture.componentInstance.position = NbPosition.LEFT;
+
+ fixture.detectChanges();
+
+ expect(componentSpy).toHaveBeenCalledTimes(1);
+ expect(componentSpy).toHaveBeenCalledWith(NbContextMenuComponent);
+ expect(hostSpy).toHaveBeenCalledWith(fixture.componentInstance.button);
+ expect(hostSpy).toHaveBeenCalledTimes(1);
+ expect(offsetSpy).toHaveBeenCalledTimes(0);
+ expect(positionSpy).toHaveBeenCalledTimes(3);
+ expect(positionSpy).toHaveBeenCalledWith(NbPosition.LEFT);
+ expect(triggerSpy).toHaveBeenCalledTimes(3);
+ expect(triggerSpy).toHaveBeenCalledWith(NbTrigger.HOVER);
+ expect(adjustmentSpy).toHaveBeenCalledTimes(3);
+ expect(adjustmentSpy).toHaveBeenCalledWith(NbAdjustment.HORIZONTAL);
+ expect(contentSpy).toHaveBeenCalledTimes(0);
+ expect(contextSpy).toHaveBeenCalledTimes(3);
+ expect(contextSpy).toHaveBeenCalledWith({
+ position: NbPosition.LEFT,
+ items: [{ title: 'New' }],
+ tag: 'new',
+ });
+ expect(buildSpy).toHaveBeenCalledTimes(1);
+ expect(rebuildSpy).toHaveBeenCalledTimes(2);
+ });
});
- const mockTriggerStrategy = bed.get(NbTriggerStrategyBuilderService);
- fixture = TestBed.createComponent(NbContextMenuTestComponent);
- fixture.componentInstance.trigger = NbTrigger.HOVER;
- fixture.detectChanges();
- expect(mockTriggerStrategy._trigger).toBe(NbTrigger.HOVER);
+ describe('instance context-menu', () => {
+
+ let fixture: ComponentFixture;
+
+ afterEach(() => {
+ fixture.destroy();
+ });
+
+ it('should rebuild', () => {
+
+ const componentSpy = spyOn(overlayHandler, 'componentType').and.callThrough();
+ const hostSpy = spyOn(overlayHandler, 'host').and.callThrough();
+ const positionSpy = spyOn(overlayHandler, 'position').and.callThrough();
+ const triggerSpy = spyOn(overlayHandler, 'trigger').and.callThrough();
+ const adjustmentSpy = spyOn(overlayHandler, 'adjustment').and.callThrough();
+ const contentSpy = spyOn(overlayHandler, 'content').and.callThrough();
+ const contextSpy = spyOn(overlayHandler, 'context').and.callThrough();
+ const offsetSpy = spyOn(overlayHandler, 'offset').and.callThrough();
+ const buildSpy = spyOn(overlayHandler, 'build').and.callThrough();
+ const rebuildSpy = spyOn(overlayHandler, 'rebuild').and.callThrough();
+
+ fixture = TestBed.createComponent(NbContextMenuInstanceTestComponent);
+ fixture.detectChanges();
+
+ fixture.componentInstance.contextMenu.adjustment = NbAdjustment.HORIZONTAL;
+ fixture.componentInstance.contextMenu.trigger = NbTrigger.HOVER;
+ fixture.componentInstance.contextMenu.items = [{ title: 'New' }];
+ fixture.componentInstance.contextMenu.tag = 'new';
+ fixture.componentInstance.contextMenu.position = NbPosition.LEFT;
+
+ fixture.componentInstance.contextMenu.rebuild();
+
+ expect(componentSpy).toHaveBeenCalledTimes(1);
+ expect(componentSpy).toHaveBeenCalledWith(NbContextMenuComponent);
+ expect(hostSpy).toHaveBeenCalledWith(fixture.componentInstance.button);
+ expect(hostSpy).toHaveBeenCalledTimes(1);
+ expect(positionSpy).toHaveBeenCalledTimes(3);
+ expect(positionSpy).toHaveBeenCalledWith(NbPosition.LEFT);
+ expect(triggerSpy).toHaveBeenCalledTimes(3);
+ expect(triggerSpy).toHaveBeenCalledWith(NbTrigger.HOVER);
+ expect(offsetSpy).toHaveBeenCalledTimes(0);
+ expect(adjustmentSpy).toHaveBeenCalledTimes(3);
+ expect(adjustmentSpy).toHaveBeenCalledWith(NbAdjustment.HORIZONTAL);
+ expect(contentSpy).toHaveBeenCalledTimes(0);
+ expect(contextSpy).toHaveBeenCalledTimes(3);
+ expect(contextSpy).toHaveBeenCalledWith({
+ position: NbPosition.LEFT,
+ items: [{ title: 'New' }],
+ tag: 'new',
+ });
+ expect(buildSpy).toHaveBeenCalledTimes(1);
+ expect(rebuildSpy).toHaveBeenCalledTimes(2);
+ });
+
+ });
});
});
diff --git a/src/framework/theme/index.ts b/src/framework/theme/index.ts
index 4635962b4b..e9eaaa52b8 100644
--- a/src/framework/theme/index.ts
+++ b/src/framework/theme/index.ts
@@ -39,6 +39,7 @@ export * from './components/badge/badge.module';
export * from './components/popover/popover.directive';
export * from './components/popover/popover.module';
export * from './components/context-menu/context-menu.directive';
+export * from './components/context-menu/context-menu.component';
export * from './components/context-menu/context-menu.module';
export * from './components/progress-bar/progress-bar.component';
export * from './components/progress-bar/progress-bar.module';