Filter-basic-chips with resize
unknown
typescript
a year ago
6.7 kB
4
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