Created
November 17, 2024 03:22
-
-
Save nathonius/758c92d81c351009d89d19688ef57667 to your computer and use it in GitHub Desktop.
Angular directive to set font size based on an element's container size
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import type { OnInit, OnChanges, SimpleChanges } from '@angular/core'; | |
import { ElementRef, Renderer2, Directive, inject, input } from '@angular/core'; | |
import { Subject } from 'rxjs'; | |
import { debounceTime } from 'rxjs/operators'; | |
@Directive({ | |
selector: '[fittext]', | |
standalone: true, | |
}) | |
export class FitTextDirective implements OnInit, OnChanges { | |
public readonly compressor = input<number>(1); // Compression factor, default is 1 | |
public readonly minFontSize = input<number>(0); // Minimum font size in pixels | |
public readonly maxFontSize = input<number>(Number.POSITIVE_INFINITY); // Maximum font size in pixels | |
public readonly debounceTime = input<number>(250); // Debounce time in milliseconds | |
private resizeSubject = new Subject<void>(); | |
private el = inject(ElementRef); | |
private renderer = inject(Renderer2); | |
ngOnInit() { | |
this.resizeSubject | |
.pipe(debounceTime(this.debounceTime())) | |
.subscribe(() => this.adjustFontSize()); | |
// Adjust font size initially | |
this.adjustFontSize(); | |
// Listen for window resize events | |
window.addEventListener('resize', () => this.resizeSubject.next()); | |
} | |
ngOnChanges(changes: SimpleChanges) { | |
if ( | |
changes['compressor'] || | |
changes['minFontSize'] || | |
changes['maxFontSize'] | |
) { | |
this.adjustFontSize(); | |
} | |
} | |
private adjustFontSize() { | |
const element = this.el.nativeElement; | |
const parentWidth = element.parentElement.offsetWidth; | |
const newFontSize = Math.max( | |
Math.min(parentWidth / (this.compressor() * 10), this.maxFontSize()), | |
this.minFontSize() | |
); | |
this.renderer.setStyle(element, 'fontSize', `${newFontSize}px`); | |
} | |
ngOnDestroy() { | |
this.resizeSubject.complete(); | |
window.removeEventListener('resize', () => this.resizeSubject.next()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment