File

projects/rebirth-ng/src/lib/common/resizeable.directive.ts

Implements

OnDestroy AfterViewInit

Metadata

selector [reResizeable]

Index

Properties
Methods
Inputs
Outputs
HostListeners

Constructor

constructor(element: ElementRef, renderer: Renderer2)
Parameters :
Name Type Optional
element ElementRef no
renderer Renderer2 no

Inputs

maxWidth

Type: number

minWidth

Type: number

reResizeable

Default value: true

Outputs

resize $event type: EventEmitter

HostListeners

mousedown
Arguments : '$event'
mousedown(event: MouseEvent)

Methods

Private _destroySubscription
_destroySubscription()
Returns : void
move
move(event: MouseEvent, initialWidth: number, mouseDownScreenX: number)
Parameters :
Name Type Optional
event MouseEvent no
initialWidth number no
mouseDownScreenX number no
Returns : void
ngAfterViewInit
ngAfterViewInit()
Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
onMouseup
onMouseup()
Returns : void

Properties

element
element: HTMLElement
Type : HTMLElement
resizing
resizing:
Default value : false
subscription
subscription: Subscription
Type : Subscription
import {
  Directive, ElementRef, HostListener, Input, Output, EventEmitter, OnDestroy, AfterViewInit, Renderer2
} from '@angular/core';
import { Subscription, fromEvent } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

@Directive({
  selector: '[reResizeable]',
  host: {
    '[class.resizeable]': 'resizeEnabled'
  }
})
export class ResizeableDirective implements OnDestroy, AfterViewInit {

  @Input('reResizeable') resizeEnabled = true;
  @Input() minWidth: number;
  @Input() maxWidth: number;

  @Output() resize = new EventEmitter<any>();

  element: HTMLElement;
  subscription: Subscription;
  resizing = false;

  constructor(element: ElementRef, private renderer: Renderer2) {
    this.element = element.nativeElement;
  }

  ngAfterViewInit(): void {
    if (this.resizeEnabled) {
      const node = this.renderer.createElement('span');
      this.renderer.addClass(node, 'resize-handle');
      this.renderer.appendChild(this.element, node);
    }
  }

  ngOnDestroy(): void {
    this._destroySubscription();
  }

  onMouseup(): void {
    this.resizing = false;

    if (this.subscription && !this.subscription.closed) {
      this._destroySubscription();
      this.resize.emit(this.element.clientWidth);
    }
  }

  @HostListener('mousedown', ['$event'])
  onMousedown(event: MouseEvent): void {
    const isHandle = (<HTMLElement>(event.target)).classList.contains('resize-handle');
    const initialWidth = this.element.clientWidth;
    const mouseDownScreenX = event.screenX;

    if (isHandle) {
      event.stopPropagation();
      this.resizing = true;

      const mouseup = fromEvent(document, 'mouseup');
      this.subscription = mouseup
        .subscribe((ev: MouseEvent) => this.onMouseup());

      const mouseMoveSub = fromEvent(document, 'mousemove')
        .pipe(takeUntil(mouseup))
        .subscribe((e: MouseEvent) => this.move(e, initialWidth, mouseDownScreenX));

      this.subscription.add(mouseMoveSub);
    }
  }

  move(event: MouseEvent, initialWidth: number, mouseDownScreenX: number): void {
    const movementX = event.screenX - mouseDownScreenX;
    const newWidth = initialWidth + movementX;

    const overMinWidth = !this.minWidth || newWidth >= this.minWidth;
    const underMaxWidth = !this.maxWidth || newWidth <= this.maxWidth;

    if (overMinWidth && underMaxWidth) {
      this.renderer.setStyle(this.element, 'width', `${newWidth}px`);
    }
  }

  private _destroySubscription() {
    if (this.subscription) {
      this.subscription.unsubscribe();
      this.subscription = undefined;
    }
  }

}

results matching ""

    No results matching ""