/** @import { Action, ActionReturn } from '../action/public' */ /** @import { Attachment } from './public' */ import { noop, render_effect } from 'svelte/internal/client'; import { ATTACHMENT_KEY } from '../constants.js'; import { untrack } from '../index-client.js'; import { teardown } from '../internal/client/reactivity/effects.js'; /** * Creates an object key that will be recognised as an attachment when the object is spread onto an element, * as a programmatic alternative to using `{@attach ...}`. This can be useful for library authors, though * is generally not needed when building an app. * * ```svelte * * * * ``` * @since 5.29 */ export function createAttachmentKey() { return Symbol(ATTACHMENT_KEY); } /** * Converts an [action](https://svelte.dev/docs/svelte/use) into an [attachment](https://svelte.dev/docs/svelte/@attach) keeping the same behavior. * It's useful if you want to start using attachments on components but you have actions provided by a library. * * Note that the second argument, if provided, must be a function that _returns_ the argument to the * action function, not the argument itself. * * ```svelte * *
...
* * *
bar)}>...
* ``` * @template {EventTarget} E * @template {unknown} T * @overload * @param {Action | ((element: E, arg: T) => void | ActionReturn)} action The action function * @param {() => T} fn A function that returns the argument for the action * @returns {Attachment} */ /** * Converts an [action](https://svelte.dev/docs/svelte/use) into an [attachment](https://svelte.dev/docs/svelte/@attach) keeping the same behavior. * It's useful if you want to start using attachments on components but you have actions provided by a library. * * Note that the second argument, if provided, must be a function that _returns_ the argument to the * action function, not the argument itself. * * ```svelte * *
...
* * *
bar)}>...
* ``` * @template {EventTarget} E * @overload * @param {Action | ((element: E) => void | ActionReturn)} action The action function * @returns {Attachment} */ /** * Converts an [action](https://svelte.dev/docs/svelte/use) into an [attachment](https://svelte.dev/docs/svelte/@attach) keeping the same behavior. * It's useful if you want to start using attachments on components but you have actions provided by a library. * * Note that the second argument, if provided, must be a function that _returns_ the argument to the * action function, not the argument itself. * * ```svelte * *
...
* * *
bar)}>...
* ``` * * @template {EventTarget} E * @template {unknown} T * @param {Action | ((element: E, arg: T) => void | ActionReturn)} action The action function * @param {() => T} fn A function that returns the argument for the action * @returns {Attachment} * @since 5.32 */ export function fromAction(action, fn = /** @type {() => T} */ (noop)) { return (element) => { const { update, destroy } = untrack(() => action(element, fn()) ?? {}); if (update) { var ran = false; render_effect(() => { const arg = fn(); if (ran) update(arg); }); ran = true; } if (destroy) { teardown(destroy); } }; }