import { defineTrait } from '../define.js';

export const resizeObserver = defineTrait({
  name: 'resize-observer',
  category: 'layout-measurement',
  description: 'Reacts to element size changes',
  attributes: ['data-resize-observer-observed', 'data-resize-width', 'data-resize-height'],
  events: ['element-resize'],
  config: [],
  setup({ host }) {
    // Guard for older browsers + non-DOM test environments (happy-dom, jsdom
    // without polyfill). The trait becomes a no-op rather than throwing on
    // the `new ResizeObserver` call.
    if (typeof ResizeObserver === 'undefined') return () => {};

    const observer = new ResizeObserver((entries) => {
      for (const entry of entries) {
        const { width, height } = entry.contentRect;
        host.setAttribute('data-resize-width', Math.round(width));
        host.setAttribute('data-resize-height', Math.round(height));
        host.dispatchEvent(new CustomEvent('element-resize', {
          bubbles: true,
          detail: { width, height },
        }));
      }
    });

    observer.observe(host);
    host.setAttribute('data-resize-observer-observed', '');

    return () => {
      observer.disconnect();
      host.removeAttribute('data-resize-observer-observed');
      host.removeAttribute('data-resize-width');
      host.removeAttribute('data-resize-height');
    };
  },
});
