Skip to content

Instantly share code, notes, and snippets.

@ferrerojosh
Last active June 8, 2017 05:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ferrerojosh/fb9865146e59e3ea1ab7d97ed78a362b to your computer and use it in GitHub Desktop.
Save ferrerojosh/fb9865146e59e3ea1ab7d97ed78a362b to your computer and use it in GitHub Desktop.
A quick splitter control for angular material sidenav for Angular 2/4
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) {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment