|
import { AfterViewInit, ContentChild, Directive, ElementRef, Input, Renderer2 } from '@angular/core'; |
|
import { Observable } from 'rxjs/Observable'; |
|
import { MdSidenav } from '@angular/material'; |
|
|
|
@Directive({ |
|
selector: '[mdSidenavSplitter]' |
|
}) |
|
export class MdSidenavSplitterDirective implements AfterViewInit { |
|
@ContentChild(MdSidenav, {read: ElementRef}) sidenavRef: ElementRef; |
|
@Input() splitterWidth = 10; |
|
|
|
ngAfterViewInit(): void { |
|
const container = this.elementRef.nativeElement; |
|
const sidenav = this.sidenavRef.nativeElement; |
|
const resizer = this.renderer.createElement('div'); |
|
const left = sidenav.clientWidth - this.splitterWidth; |
|
|
|
// basic styling |
|
this.renderer.setAttribute(resizer, 'class', 'mat-sidenav-splitter'); |
|
this.renderer.setStyle(resizer, 'background', 'url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==")'); |
|
this.renderer.setStyle(resizer, 'background-color', '#eeeeee'); |
|
this.renderer.setStyle(resizer, 'background-position', 'center center'); |
|
this.renderer.setStyle(resizer, 'background-repeat', 'no-repeat'); |
|
this.renderer.setStyle(resizer, 'position', 'absolute'); |
|
this.renderer.setStyle(resizer, 'top', '0'); |
|
this.renderer.setStyle(resizer, 'bottom', '0'); |
|
this.renderer.setStyle(resizer, 'left', left + 'px'); |
|
this.renderer.setStyle(resizer, 'width', this.splitterWidth + 'px'); |
|
this.renderer.setStyle(resizer, 'cursor', 'col-resize'); |
|
this.renderer.appendChild(sidenav, resizer); |
|
|
|
const onUp = Observable.fromEvent(container, 'mouseup'); |
|
const onMove = Observable.fromEvent(container, 'mousemove'); |
|
const onDown = Observable.fromEvent(resizer, 'mousedown').map((event: Event) => event.preventDefault()); |
|
|
|
const onDrag = onDown.flatMap(() => { |
|
return onMove.map(pos => { |
|
return pos; |
|
}).takeUntil(onUp); |
|
}); |
|
|
|
onDrag.subscribe((data: MouseEvent) => { |
|
const posX = (data.clientX - this.splitterWidth); |
|
this.renderer.setStyle(sidenav, 'width', data.clientX + 'px'); |
|
this.renderer.setStyle(resizer, 'left', posX + 'px'); |
|
}); |
|
} |
|
|
|
constructor(private elementRef: ElementRef, |
|
private renderer: Renderer2) {} |
|
|
|
} |