import { LitElement, css } from 'lit'; import { html } from 'lit/html.js'; import { customElement } from 'lit/decorators.js'; // taken here: https://github.com/shoelace-style/shoelace/blob/next/src/components/resize-observer/resize-observer.ts @customElement('mono-resize-observer') export class MonoResizeObserverComp extends LitElement { static styles = css` :host { display: contents; } `; private __resizeObserver?: ResizeObserver; private __observedElements: HTMLElement[] = []; connectedCallback() { // eslint-disable-next-line wc/guard-super-call super.connectedCallback(); this.__resizeObserver = new ResizeObserver( (entries: ResizeObserverEntry[]) => { window.requestAnimationFrame(() => { const event = new CustomEvent('mono-resize', { detail: { entries }, bubbles: true, composed: true, }); this.dispatchEvent(event); }); }, ); } disconnectedCallback() { // eslint-disable-next-line wc/guard-super-call super.disconnectedCallback(); this.__resizeObserver?.disconnect(); } __handleSlotChange() { const slot = this.shadowRoot!.querySelector('slot')!; const elements = slot.assignedElements({ flatten: true }) as HTMLElement[]; // Unwatch previous elements this.__observedElements.map((el) => this.__resizeObserver?.unobserve(el)); this.__observedElements = []; // Watch new elements elements.forEach((el) => { this.__resizeObserver?.observe(el); this.__observedElements.push(el); }); } render() { return html` `; } } declare global { interface HTMLElementTagNameMap { 'mono-resize-observer': MonoResizeObserverComp; } }