Skip to content

Instantly share code, notes, and snippets.

@nathonius
Created November 17, 2024 03:22
Show Gist options
  • Save nathonius/758c92d81c351009d89d19688ef57667 to your computer and use it in GitHub Desktop.
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
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