import { Directive, ElementRef, OnInit, AfterContentInit, HostListener } from '@angular/core';
/**
* Den första textarean (förslagsvis den enda) i komponenten som fbElastic appliceras på blir elastisk. Textareas som fbElastic appliceras på blir elastiska.
*
* Syntax:
*
*
*
*/
@Directive({
selector: '[fbElastic]'
})
export class FbElasticDirective implements OnInit, AfterContentInit {
private element: HTMLElement;
private textarea: HTMLTextAreaElement;
constructor(elemntRef: ElementRef) {
this.element = elemntRef.nativeElement;
}
ngOnInit(): void {
// Use first textarea child if component is not a textarea
this.textarea = this.element.tagName === 'TEXTAREA' ? this.element as HTMLTextAreaElement :
this.element.getElementsByTagName('textarea')[0];
}
ngAfterContentInit(): void {
// Initial adjust on initial render
setTimeout(() => {
this.adjust.bind(this);
this.adjust(0);
}, 0); // "Que" adjust to be ran after template is rendered. Event loop lecture: https://www.youtube.com/watch?v=8aGhZQkoFbQ
}
@HostListener('input')
onInput(): void {
// This is run whenever the user changes the input.
this.adjust(0);
}
@HostListener('blur')
onblur(): void {
setTimeout(() => {
this.adjust.bind(this);
this.adjust(0);
}, 0); // "Que" adjust to be ran after the model has updated (for anteckning).
}
adjust(antal: number): void {
// Width < 10 happens when the element is not rendered, wait 100ms and then try again, stop trying after 5 tries, just to stop it from looping forever
if (this.textarea) {
if (this.textarea.clientWidth < 10 && antal < 5) {
setTimeout(() => {
this.adjust(antal++);
}, 100);
} else {
this.textarea.style.height = 'auto'; // This decreases height
// The Element.scrollHeight read-only property is a measurement of the height of an element's content, including content not visible on the screen due to overflow.
this.textarea.style.height = this.textarea.scrollHeight + 'px'; // This increases height
}
}
}
}