import { untrack } from "svelte"; import { isBox } from "../box/box-extras.svelte.js"; import { createAttachmentKey } from "svelte/attachments"; /** * Creates a Svelte Attachment that attaches a DOM element to a ref. * The ref can be either a WritableBox or a callback function. * * @param ref - Either a WritableBox to store the element in, or a callback function that receives the element * @param onChange - Optional callback that fires when the ref changes * @returns An object with a spreadable attachment key that should be spread onto the element * * @example * // Using with WritableBox * const ref = box(null); *
Content
* * @example * // Using with callback *
myNode = node)}>Content
* * @example * // Using with onChange *
console.log(node))}>Content
*/ export function attachRef(ref, onChange) { return { [createAttachmentKey()]: (node) => { if (isBox(ref)) { ref.current = node; untrack(() => onChange?.(node)); return () => { // we don't want to detach the node if it's still connected if ("isConnected" in node && node.isConnected) return; ref.current = null; onChange?.(null); }; } ref(node); untrack(() => onChange?.(node)); return () => { // we don't want to detach the node if it's still connected if ("isConnected" in node && node.isConnected) return; ref(null); onChange?.(null); }; } }; }