red-ui/apps/red-ui/src/app/modules/shared/directives/sync-width.directive.ts
2021-07-23 03:09:30 +03:00

78 lines
2.3 KiB
TypeScript

import { AfterViewInit, Directive, ElementRef, HostListener, Input, OnDestroy } from '@angular/core';
import { debounce } from '@utils/debounce';
@Directive({
selector: '[redactionSyncWidth]',
exportAs: 'redactionSyncWidth'
})
export class SyncWidthDirective implements AfterViewInit, OnDestroy {
@Input()
redactionSyncWidth: string;
private _interval: number;
constructor(private readonly _elementRef: ElementRef) {}
ngAfterViewInit(): void {
this._interval = setInterval(() => {
this.matchWidth();
}, 1000);
}
ngOnDestroy(): void {
clearInterval(this._interval);
}
@debounce(10)
matchWidth() {
const headerItems = this._elementRef.nativeElement.children;
const tableRows = document.getElementsByClassName(this.redactionSyncWidth);
// const tableRows = this._elementRef.nativeElement.parentElement.getElementsByClassName(this.redactionSyncWidth);
if (!tableRows || !tableRows.length) {
return;
}
this._elementRef.nativeElement.setAttribute('synced', true);
const { tableRow, length } = this._sampleRow(tableRows);
const hasExtraColumns = headerItems.length !== length ? 1 : 0;
for (let idx = 0; idx < length - hasExtraColumns - 1; ++idx) {
if (headerItems[idx]) {
headerItems[idx].style.width = `${tableRow.children[idx].getBoundingClientRect().width}px`;
headerItems[idx].style.minWidth = `${tableRow.children[idx].getBoundingClientRect().width}px`;
}
}
for (let idx = length - hasExtraColumns - 1; idx < headerItems.length; ++idx) {
if (headerItems[idx]) {
headerItems[idx].style.minWidth = `0`;
}
}
}
@HostListener('window:resize')
onResize() {
this.matchWidth();
}
private _sampleRow(tableRows: HTMLCollectionOf<Element>): {
tableRow: Element;
length: number;
} {
let length = 0;
let tableRow: Element;
for (let idx = 0; idx < tableRows.length; ++idx) {
const row = tableRows.item(idx);
if (row.children.length > length) {
length = row.children.length;
tableRow = row;
}
}
return { tableRow, length };
}
}