diff --git a/src/framework/theme/components/sidebar/sidebar.component.ts b/src/framework/theme/components/sidebar/sidebar.component.ts
index e36614744c..e438f661ec 100644
--- a/src/framework/theme/components/sidebar/sidebar.component.ts
+++ b/src/framework/theme/components/sidebar/sidebar.component.ts
@@ -338,15 +338,8 @@ export class NbSidebarComponent implements OnChanges, OnInit, OnDestroy {
const menu = this.element.nativeElement.querySelector('nb-menu');
if (menu && menu.contains(event.target)) {
- let link = event.target;
- const linkChildren = ['span', 'i'];
+ const link = this.getMenuLink(event.target);
- // if we clicked on span - get the link
- if (linkChildren.includes(link.tagName.toLowerCase()) && link.parentNode) {
- link = event.target.parentNode;
- }
-
- // we only expand if an item has children
if (link && link.nextElementSibling && link.nextElementSibling.classList.contains('menu-items')) {
this.expand();
}
@@ -430,4 +423,16 @@ export class NbSidebarComponent implements OnChanges, OnInit, OnDestroy {
protected responsiveEnabled(): boolean {
return this.responsiveValue;
}
+
+ protected getMenuLink(element: HTMLElement): HTMLElement | undefined {
+ if (!element || element.tagName.toLowerCase() === 'nb-menu') {
+ return;
+ }
+
+ if (element.tagName.toLowerCase() === 'a') {
+ return element;
+ }
+
+ return this.getMenuLink(element.parentElement);
+ }
}
diff --git a/src/framework/theme/components/sidebar/sidebar.spec.ts b/src/framework/theme/components/sidebar/sidebar.spec.ts
new file mode 100644
index 0000000000..676691955a
--- /dev/null
+++ b/src/framework/theme/components/sidebar/sidebar.spec.ts
@@ -0,0 +1,134 @@
+import { Component, DebugElement } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+import { RouterTestingModule } from '@angular/router/testing';
+import { NoopAnimationsModule } from '@angular/platform-browser/animations';
+import {
+ NbSidebarComponent,
+ NbMenuModule,
+ NbMenuItem,
+ NbSidebarModule,
+ NbMenuComponent,
+ NbThemeModule,
+ NbMenuItemComponent, NbIconComponent,
+} from '@nebular/theme';
+
+@Component({
+ template: `
+
+
+
+
+ `,
+})
+export class SidebarExpandTestComponent {
+ menuItems: NbMenuItem[] = [
+ {
+ title: 'no children',
+ },
+ {
+ title: 'parent',
+ children: [ { title: 'child' } ],
+ },
+ {
+ title: 'group',
+ group: true,
+ },
+ ];
+}
+
+describe('NbSidebarComponent', () => {
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ RouterTestingModule.withRoutes([]),
+ NoopAnimationsModule,
+ NbThemeModule.forRoot(),
+ NbSidebarModule.forRoot(),
+ NbMenuModule.forRoot(),
+ ],
+ declarations: [ SidebarExpandTestComponent ],
+ });
+ });
+
+ describe('States (expanded, collapsed, compacted)', () => {
+ let fixture: ComponentFixture;
+ let sidebarComponent: NbSidebarComponent;
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(SidebarExpandTestComponent);
+ fixture.detectChanges();
+
+ sidebarComponent = fixture.debugElement.query(By.directive(NbSidebarComponent)).componentInstance;
+ });
+
+ it(`should collapse when collapse method called`, () => {
+ sidebarComponent.collapse();
+ fixture.detectChanges();
+
+ expect(sidebarComponent.expanded).toEqual(false);
+ });
+
+ it('should become compacted when compact method called', () => {
+ sidebarComponent.compact();
+ fixture.detectChanges();
+
+ expect(sidebarComponent.compacted).toEqual(true);
+ });
+
+ it('should not expand when clicked outside menu', () => {
+ const buttonOutsideMenu: DebugElement = fixture.debugElement.query(By.css('#button-outside-menu'));
+ sidebarComponent.compact();
+ fixture.detectChanges();
+
+ buttonOutsideMenu.nativeElement.click();
+ fixture.detectChanges();
+
+ expect(sidebarComponent.compacted).toEqual(true);
+ });
+
+ it('should not expand when clicked on menu item without children', () => {
+ sidebarComponent.compact();
+ fixture.detectChanges();
+
+ const menuItemWithNoChildren: DebugElement = fixture.debugElement.query(By.directive(NbMenuComponent));
+ menuItemWithNoChildren.nativeElement.click();
+ fixture.detectChanges();
+
+ expect(sidebarComponent.compacted).toEqual(true);
+ });
+
+ it('should not expand when clicked on menu group', () => {
+ sidebarComponent.compact();
+ fixture.detectChanges();
+
+ const menuGroup: DebugElement = fixture.debugElement.queryAll(By.directive(NbMenuItemComponent))[3];
+ menuGroup.query(By.css('span')).nativeElement.click();
+ fixture.detectChanges();
+
+ expect(sidebarComponent.compacted).toEqual(true);
+ });
+
+ it('should expand when icon of menu item with child items clicked', () => {
+ sidebarComponent.compact();
+ fixture.detectChanges();
+
+ const menuItemWithChildren: DebugElement = fixture.debugElement.queryAll(By.directive(NbMenuItemComponent))[1];
+ menuItemWithChildren.query(By.directive(NbIconComponent)).nativeElement.click();
+ fixture.detectChanges();
+
+ expect(sidebarComponent.expanded).toEqual(true);
+ });
+
+ it('should expand when link of menu item with child items clicked', () => {
+ sidebarComponent.compact();
+ fixture.detectChanges();
+
+ const menuItemWithChildren: DebugElement = fixture.debugElement.queryAll(By.directive(NbMenuItemComponent))[1];
+ menuItemWithChildren.query(By.css('a')).nativeElement.click();
+ fixture.detectChanges();
+
+ expect(sidebarComponent.expanded).toEqual(true);
+ });
+ });
+});