import { Observable } from 'rxjs'; import { debounceTime, filter, map, pairwise, startWith } from 'rxjs/operators'; export const observeResize = ( element: Element, emitOnStart?: boolean, debounce?: number, observe?: 'VERTICAL' | 'HORIZONTAL' | 'ALL' ): Observable => { const initial: DOMRect = element.getBoundingClientRect(); let observable = new Observable(subscriber => { const resizeObserver = new ResizeObserver(entries => { entries.forEach(entry => { if (entry.target === element) subscriber.next(entry.contentRect); }); }); resizeObserver.observe(element, { box: 'border-box' }); return () => { resizeObserver.unobserve(element); resizeObserver.disconnect(); }; }); if (debounce) observable = observable.pipe(debounceTime(debounce)); observable = observable.pipe( startWith(initial), pairwise(), filter(([previous, current]) => { switch (observe) { case 'HORIZONTAL': return previous.width !== current.width; case 'VERTICAL': return previous.height !== current.height; default: return true; } }), map(([_, current]) => current) ); if (emitOnStart) observable = observable.pipe(startWith(initial)); return observable; };