/**
 * Svelte action that re-parents a node to document.body (or any selector).
 *
 * Use this for popups / dropdowns / tooltips that rely on
 * `position: fixed` positioning. Any ancestor with `backdrop-filter`,
 * `transform`, `filter`, `perspective`, `contain: paint`, or
 * `will-change: transform` becomes the containing block for fixed
 * descendants — which silently breaks viewport-relative positioning.
 *
 * Portalling sidesteps that by detaching the node from the component
 * tree and appending it to a target outside any such ancestor.
 *
 * Usage:
 *   <div use:portal>...</div>          // → document.body
 *   <div use:portal={'#root'}>...</div> // → custom selector
 */
export type PortalTarget = string | HTMLElement;

export function portal(node: HTMLElement, target: PortalTarget = 'body') {
	function attach(t: PortalTarget) {
		const el = typeof t === 'string' ? document.querySelector(t) : t;
		if (el instanceof HTMLElement) el.appendChild(node);
	}

	attach(target);

	return {
		update(newTarget: PortalTarget) {
			attach(newTarget);
		},
		destroy() {
			node.parentNode?.removeChild(node);
		},
	};
}
