Filter-basic-chips with resize
unknown
typescript
2 years ago
6.7 kB
5
Indexable
import {
ChangeDetectorRef,
Component,
ElementRef,
EventEmitter,
HostListener,
Input,
OnChanges,
OnInit,
Output,
SimpleChanges,
ViewChild,
} from '@angular/core';
import { FilterBasicSelectItem } from '../../../../../../shared';
import { WithStaticLabels } from '../../../../with-static-labels/with-static-labels';
@Component({
selector: 'app-filter-basic-chips',
templateUrl: './filter-basic-chips.component.html',
styleUrls: ['./filter-basic-chips.component.scss'],
})
export class FilterBasicChipsComponent extends WithStaticLabels implements OnInit, OnChanges {
@Input() selectedItems: FilterBasicSelectItem[] = [];
@Input() removableChips = true;
@Input() containerWidth: number;
@ViewChild('matChipsList') matChipsList: ElementRef;
@Output() chipRemoved = new EventEmitter<FilterBasicSelectItem>();
visibleChips: FilterBasicSelectItem[] = [];
visibleChipCount: number;
hideChips: boolean;
hiddenChipCount = 0;
lastWindowWidth: number;
initialChipsWidth: Record<string, number> = {};
private readonly GAP_BETWEEN_CHIPS: number = 8;
constructor(private changeDetectorRef: ChangeDetectorRef) {
super();
}
ngOnInit(): void {
this.visibleChips = this.selectedItems;
}
ngOnChanges(changes: SimpleChanges): void {
if (changes.containerWidth?.currentValue) {
this.setInitialChipsWidth();
this.calculateOverflownChips();
}
if (changes.selectedItems) {
this.visibleChips = changes.selectedItems.currentValue;
if (changes.selectedItems.currentValue && changes.selectedItems.previousValue) {
const currentLength = changes.selectedItems.currentValue.length;
const prevLength = changes.selectedItems.previousValue.length;
if (currentLength !== prevLength) {
// if (changes.selectedItems.currentValue?.length > changes.selectedItems.previousValue?.length) {
// //there are new filters, need their width in the record for correct calculation of overflow
// // this.changeDetectorRef.detectChanges();
// }
this.hideChips = false;
this.hiddenChipCount = 0;
if (currentLength > 0 && currentLength < prevLength) {
this.calculateOverflownChips();
} else {
this.changeDetectorRef.detectChanges();
this.updateChipsWidth();
this.calculateOverflownChips();
}
}
}
//selected label -> innertext.includes
}
}
ngAfterViewInit(): void {
this.lastWindowWidth = window.innerWidth;
if (this.selectedItems.length && this.containerWidth) {
this.setInitialChipsWidth();
this.calculateOverflownChips();
}
}
@HostListener('window:resize', ['$event'])
onResize(): void {
const hasWindowIncreased = window.innerWidth > this.lastWindowWidth;
this.lastWindowWidth = window.innerWidth;
if (!this.selectedItems.length) {
return;
}
if (hasWindowIncreased) {
console.log('increase');
this.showHiddenChips();
} else {
console.log('decrease');
this.calculateOverflownChips();
}
}
onChipRemoved(item: FilterBasicSelectItem): void {
this.chipRemoved.emit(item);
delete this.initialChipsWidth[item.selectedLabel];
}
setInitialChipsWidth(): void {
const matChipsWrapper = this.matChipsList.nativeElement.firstChild?.firstChild;
for (let index = 0; index < this.selectedItems.length; index++) {
this.initialChipsWidth[this.selectedItems[index].selectedLabel] = matChipsWrapper?.children[index]?.offsetWidth;
}
}
updateChipsWidth(): void {
const matChipsWrapper = this.matChipsList.nativeElement.firstChild?.firstChild;
this.visibleChips.forEach(chip => {
for (let index = 0; index < matChipsWrapper.children.length; index++) {
if (matChipsWrapper.children[index].innerText.includes(chip.selectedLabel)) {
this.initialChipsWidth[chip.selectedLabel] = matChipsWrapper.children[index].offsetWidth;
}
}
});
}
showHiddenChips(): void {
if (this.hideChips) {
const containerWidth = this.matChipsList.nativeElement.parentNode?.parentNode?.parentNode?.offsetWidth;
const matChipsWrapper = this.matChipsList.nativeElement.firstChild?.firstChild;
let totalWidth = 0;
for (let index = 0; index < this.visibleChips.length; index++) {
totalWidth += matChipsWrapper.children[index].offsetWidth + this.GAP_BETWEEN_CHIPS;
}
for (let index = this.visibleChips.length; index < this.selectedItems.length; index++) {
totalWidth += this.initialChipsWidth[this.selectedItems[index].selectedLabel] + this.GAP_BETWEEN_CHIPS;
if (totalWidth < containerWidth) {
this.visibleChipCount++;
this.visibleChips = this.selectedItems.slice(0, this.visibleChipCount);
this.hiddenChipCount--;
if (this.visibleChipCount === this.selectedItems.length) {
this.hideChips = false;
this.hiddenChipCount = 0;
}
}
}
}
}
calculateOverflownChips(): void {
// const matChipsWrapper = this.matChipsList.nativeElement.firstChild?.firstChild;
const filterBasicDiv = this.matChipsList.nativeElement.parentNode?.parentNode?.parentNode;
let chipsLength = 0;
const widthOfExtension = 36;
for (let index = 0; index < this.selectedItems.length; index++) {
chipsLength += this.initialChipsWidth[this.selectedItems[index].selectedLabel] + this.GAP_BETWEEN_CHIPS;
if (chipsLength > filterBasicDiv.offsetWidth) {
chipsLength -= this.initialChipsWidth[this.selectedItems[index].selectedLabel] + this.GAP_BETWEEN_CHIPS;
if (chipsLength + widthOfExtension > filterBasicDiv.offsetWidth) {
index--;
}
this.visibleChipCount = index;
this.hideOverflownChips();
break;
}
}
}
hideOverflownChips(): void {
this.hideChips = true;
this.visibleChips = this.selectedItems.slice(0, this.visibleChipCount);
this.hiddenChipCount = this.selectedItems.length - this.visibleChipCount;
this.changeDetectorRef.detectChanges();
}
onShowAllChips(): void {
this.hideChips = false;
this.visibleChips = this.selectedItems;
this.changeDetectorRef.detectChanges();
}
onHideChips(): void {
this.hideChips = true;
this.visibleChips = this.selectedItems.slice(0, this.selectedItems.length - this.hiddenChipCount);
this.changeDetectorRef.detectChanges();
}
}
Editor is loading...
Leave a Comment