INIT
This commit is contained in:
+50
@@ -0,0 +1,50 @@
|
||||
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<HTMLDivElement | null>(null);
|
||||
* <div {...attachRef(ref)}>Content</div>
|
||||
*
|
||||
* @example
|
||||
* // Using with callback
|
||||
* <div {...attachRef((node) => myNode = node)}>Content</div>
|
||||
*
|
||||
* @example
|
||||
* // Using with onChange
|
||||
* <div {...attachRef(ref, (node) => console.log(node))}>Content</div>
|
||||
*/
|
||||
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);
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user