fix(aio): expand the main content width when there is no ToC
Previously, the main content would always leave a 18% margin on the right to be occupied by the ToC (even if there was no ToC). This commit lets the main content expand to the right to occupy all the available space when there is no ToC. Fixes #17205 Fixes #17270
This commit is contained in:
parent
8524187869
commit
e894f5c399
|
@ -15,7 +15,7 @@
|
|||
</md-toolbar>
|
||||
<aio-search-results #searchResults *ngIf="showSearchResults" (resultSelected)="hideSearchResults()"></aio-search-results>
|
||||
|
||||
<md-sidenav-container class="sidenav-container" [class.starting]="isStarting" role="main">
|
||||
<md-sidenav-container class="sidenav-container" [class.starting]="isStarting" [class.has-floating-toc]="hasFloatingToc" role="main">
|
||||
|
||||
<md-sidenav [ngClass]="{'collapsed': !isSideBySide }" #sidenav class="sidenav" [opened]="isOpened" [mode]="mode" (open)="updateHostClasses()" (close)="updateHostClasses()">
|
||||
<aio-nav-menu *ngIf="!isSideBySide" [nodes]="topMenuNarrowNodes" [currentNode]="currentNodes?.TopBarNarrow"></aio-nav-menu>
|
||||
|
@ -33,7 +33,7 @@
|
|||
|
||||
</md-sidenav-container>
|
||||
|
||||
<div *ngIf="showFloatingToc" class="toc-container" [style.max-height.px]="tocMaxHeight" (mousewheel)="restrainScrolling($event)">
|
||||
<div *ngIf="hasFloatingToc" class="toc-container" [style.max-height.px]="tocMaxHeight" (mousewheel)="restrainScrolling($event)">
|
||||
<aio-toc></aio-toc>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { async, inject, ComponentFixture, TestBed, fakeAsync, tick } from '@angu
|
|||
import { Title } from '@angular/platform-browser';
|
||||
import { APP_BASE_HREF } from '@angular/common';
|
||||
import { Http } from '@angular/http';
|
||||
import { MdProgressBar } from '@angular/material';
|
||||
import { MdProgressBar, MdSidenav } from '@angular/material';
|
||||
import { By } from '@angular/platform-browser';
|
||||
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
|
@ -27,7 +27,7 @@ import { SearchService } from 'app/search/search.service';
|
|||
import { SelectComponent, Option } from 'app/shared/select/select.component';
|
||||
import { SwUpdateNotificationsService } from 'app/sw-updates/sw-update-notifications.service';
|
||||
import { TocComponent } from 'app/embedded/toc/toc.component';
|
||||
import { MdSidenav } from '@angular/material';
|
||||
import { TocItem, TocService } from 'app/shared/toc.service';
|
||||
|
||||
const sideBySideBreakPoint = 992;
|
||||
const hideToCBreakPoint = 800;
|
||||
|
@ -40,6 +40,7 @@ describe('AppComponent', () => {
|
|||
let hamburger: HTMLButtonElement;
|
||||
let locationService: MockLocationService;
|
||||
let sidenav: HTMLElement;
|
||||
let tocService: TocService;
|
||||
|
||||
const initializeTest = () => {
|
||||
fixture = TestBed.createComponent(AppComponent);
|
||||
|
@ -48,10 +49,12 @@ describe('AppComponent', () => {
|
|||
fixture.detectChanges();
|
||||
component.onResize(sideBySideBreakPoint + 1); // wide by default
|
||||
|
||||
docViewer = fixture.debugElement.query(By.css('aio-doc-viewer')).nativeElement;
|
||||
hamburger = fixture.debugElement.query(By.css('.hamburger')).nativeElement;
|
||||
locationService = fixture.debugElement.injector.get(LocationService) as any;
|
||||
sidenav = fixture.debugElement.query(By.css('md-sidenav')).nativeElement;
|
||||
const de = fixture.debugElement;
|
||||
docViewer = de.query(By.css('aio-doc-viewer')).nativeElement;
|
||||
hamburger = de.query(By.css('.hamburger')).nativeElement;
|
||||
locationService = de.injector.get(LocationService) as any as MockLocationService;
|
||||
sidenav = de.query(By.css('md-sidenav')).nativeElement;
|
||||
tocService = de.injector.get(TocService);
|
||||
};
|
||||
|
||||
describe('with proper DocViewer', () => {
|
||||
|
@ -72,19 +75,74 @@ describe('AppComponent', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('onResize', () => {
|
||||
it('should update `isSideBySide` accordingly', () => {
|
||||
component.onResize(sideBySideBreakPoint + 1);
|
||||
expect(component.isSideBySide).toBe(true);
|
||||
component.onResize(sideBySideBreakPoint - 1);
|
||||
expect(component.isSideBySide).toBe(false);
|
||||
describe('hasFloatingToc', () => {
|
||||
it('should initially be true', () => {
|
||||
const fixture2 = TestBed.createComponent(AppComponent);
|
||||
const component2 = fixture2.componentInstance;
|
||||
|
||||
expect(component2.hasFloatingToc).toBe(true);
|
||||
});
|
||||
|
||||
it('should update `showFloatingToc` accordingly', () => {
|
||||
component.onResize(hideToCBreakPoint + 1);
|
||||
expect(component.showFloatingToc).toBe(true);
|
||||
it('should be false on narrow screens', () => {
|
||||
component.onResize(hideToCBreakPoint - 1);
|
||||
expect(component.showFloatingToc).toBe(false);
|
||||
|
||||
tocService.tocList.next([{}, {}, {}] as TocItem[]);
|
||||
expect(component.hasFloatingToc).toBe(false);
|
||||
|
||||
tocService.tocList.next([]);
|
||||
expect(component.hasFloatingToc).toBe(false);
|
||||
|
||||
tocService.tocList.next([{}, {}, {}] as TocItem[]);
|
||||
expect(component.hasFloatingToc).toBe(false);
|
||||
});
|
||||
|
||||
it('should be true on wide screens unless the toc is empty', () => {
|
||||
component.onResize(hideToCBreakPoint + 1);
|
||||
|
||||
tocService.tocList.next([{}, {}, {}] as TocItem[]);
|
||||
expect(component.hasFloatingToc).toBe(true);
|
||||
|
||||
tocService.tocList.next([]);
|
||||
expect(component.hasFloatingToc).toBe(false);
|
||||
|
||||
tocService.tocList.next([{}, {}, {}] as TocItem[]);
|
||||
expect(component.hasFloatingToc).toBe(true);
|
||||
});
|
||||
|
||||
it('should be false when toc is empty', () => {
|
||||
tocService.tocList.next([]);
|
||||
|
||||
component.onResize(hideToCBreakPoint + 1);
|
||||
expect(component.hasFloatingToc).toBe(false);
|
||||
|
||||
component.onResize(hideToCBreakPoint - 1);
|
||||
expect(component.hasFloatingToc).toBe(false);
|
||||
|
||||
component.onResize(hideToCBreakPoint + 1);
|
||||
expect(component.hasFloatingToc).toBe(false);
|
||||
});
|
||||
|
||||
it('should be true when toc is not empty unless the screen is narrow', () => {
|
||||
tocService.tocList.next([{}, {}, {}] as TocItem[]);
|
||||
|
||||
component.onResize(hideToCBreakPoint + 1);
|
||||
expect(component.hasFloatingToc).toBe(true);
|
||||
|
||||
component.onResize(hideToCBreakPoint - 1);
|
||||
expect(component.hasFloatingToc).toBe(false);
|
||||
|
||||
component.onResize(hideToCBreakPoint + 1);
|
||||
expect(component.hasFloatingToc).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isSideBySide', () => {
|
||||
it('should be updated on resize', () => {
|
||||
component.onResize(sideBySideBreakPoint - 1);
|
||||
expect(component.isSideBySide).toBe(false);
|
||||
|
||||
component.onResize(sideBySideBreakPoint + 1);
|
||||
expect(component.isSideBySide).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -523,14 +581,31 @@ describe('AppComponent', () => {
|
|||
let tocDebugElement: DebugElement;
|
||||
let tocContainer: DebugElement;
|
||||
|
||||
beforeEach(() => {
|
||||
const setHasFloatingToc = hasFloatingToc => {
|
||||
component.hasFloatingToc = hasFloatingToc;
|
||||
fixture.detectChanges();
|
||||
|
||||
tocDebugElement = fixture.debugElement.query(By.directive(TocComponent));
|
||||
tocContainer = tocDebugElement.parent;
|
||||
tocContainer = tocDebugElement && tocDebugElement.parent;
|
||||
};
|
||||
|
||||
beforeEach(() => setHasFloatingToc(true));
|
||||
|
||||
|
||||
it('should show/hide `<aio-toc>` based on `hasFloatingToc`', () => {
|
||||
expect(tocDebugElement).toBeTruthy();
|
||||
expect(tocContainer).toBeTruthy();
|
||||
|
||||
setHasFloatingToc(false);
|
||||
expect(tocDebugElement).toBeFalsy();
|
||||
expect(tocContainer).toBeFalsy();
|
||||
|
||||
setHasFloatingToc(true);
|
||||
expect(tocDebugElement).toBeTruthy();
|
||||
expect(tocContainer).toBeTruthy();
|
||||
});
|
||||
|
||||
|
||||
it('should have a non-embedded `<aio-toc>` element', () => {
|
||||
expect(tocDebugElement).toBeDefined();
|
||||
expect(tocDebugElement.classes['embedded']).toBeFalsy();
|
||||
});
|
||||
|
||||
|
|
|
@ -12,7 +12,9 @@ import { SearchResultsComponent } from 'app/search/search-results/search-results
|
|||
import { SearchBoxComponent } from 'app/search/search-box/search-box.component';
|
||||
import { SearchService } from 'app/search/search.service';
|
||||
import { SwUpdateNotificationsService } from 'app/sw-updates/sw-update-notifications.service';
|
||||
import { TocService } from 'app/shared/toc.service';
|
||||
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
import { combineLatest } from 'rxjs/observable/combineLatest';
|
||||
|
||||
const sideNavView = 'SideNav';
|
||||
|
@ -65,8 +67,9 @@ export class AppComponent implements OnInit {
|
|||
topMenuNodes: NavigationNode[];
|
||||
topMenuNarrowNodes: NavigationNode[];
|
||||
|
||||
showFloatingToc = false;
|
||||
showFloatingTocWidth = 800;
|
||||
hasFloatingToc = true;
|
||||
private showFloatingToc = new BehaviorSubject(false);
|
||||
private showFloatingTocWidth = 800;
|
||||
tocMaxHeight: string;
|
||||
private tocMaxHeightOffset = 0;
|
||||
|
||||
|
@ -103,7 +106,8 @@ export class AppComponent implements OnInit {
|
|||
private navigationService: NavigationService,
|
||||
private scrollService: ScrollService,
|
||||
private searchService: SearchService,
|
||||
private swUpdateNotifications: SwUpdateNotificationsService
|
||||
private swUpdateNotifications: SwUpdateNotificationsService,
|
||||
private tocService: TocService
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
|
@ -174,6 +178,10 @@ export class AppComponent implements OnInit {
|
|||
this.navigationService.versionInfo.subscribe( vi => this.versionInfo = vi );
|
||||
|
||||
this.swUpdateNotifications.enable();
|
||||
|
||||
const hasNonEmptyToc = this.tocService.tocList.map(tocList => tocList.length > 0);
|
||||
combineLatest(hasNonEmptyToc, this.showFloatingToc)
|
||||
.subscribe(([hasToc, showFloatingToc]) => this.hasFloatingToc = hasToc && showFloatingToc);
|
||||
}
|
||||
|
||||
// Scroll to the anchor in the hash fragment or top of doc.
|
||||
|
@ -207,7 +215,7 @@ export class AppComponent implements OnInit {
|
|||
@HostListener('window:resize', ['$event.target.innerWidth'])
|
||||
onResize(width) {
|
||||
this.isSideBySide = width > this.sideBySideWidth;
|
||||
this.showFloatingToc = width > this.showFloatingTocWidth;
|
||||
this.showFloatingToc.next(width > this.showFloatingTocWidth);
|
||||
}
|
||||
|
||||
@HostListener('click', ['$event.target', '$event.button', '$event.ctrlKey', '$event.metaKey', '$event.altKey'])
|
||||
|
|
|
@ -42,12 +42,12 @@ md-sidenav.mat-sidenav.sidenav {
|
|||
md-sidenav-container.sidenav-container {
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
max-width: 82%;
|
||||
max-width: 100%;
|
||||
margin: 0;
|
||||
transform: none;
|
||||
|
||||
@media (max-width: 800px) {
|
||||
max-width: 100%;
|
||||
&.has-floating-toc {
|
||||
max-width: 82%;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue