remove FromAction interface

pull/15958/head
Rich Harris 4 months ago
parent 42662e4008
commit 585d81c939

@ -1,4 +1,5 @@
/** @import { FromAction } from './public.js' */ /** @import { Action, ActionReturn } from 'svelte/action' */
/** @import { Attachment } from 'svelte/attachments' */
import { noop, render_effect } from 'svelte/internal/client'; import { noop, render_effect } from 'svelte/internal/client';
import { ATTACHMENT_KEY } from '../constants.js'; import { ATTACHMENT_KEY } from '../constants.js';
import { untrack } from 'svelte'; import { untrack } from 'svelte';
@ -33,17 +34,25 @@ export function createAttachmentKey() {
/** /**
* Converts an Action into an Attachment keeping the same behavior. It's useful if you want to start using * Converts an Action into an Attachment keeping the same behavior. It's useful if you want to start using
* attachments on Components but you have library provided actions. * attachments on Components but you have library provided actions.
* @type {FromAction} *
* Note that the second argument, if provided, must be a function that _returns_ the argument to the
* action function, not the argument itself.
*
* @template {EventTarget} E
* @template {unknown} T
* @param {Action<E, T> | function(E, T): void | ActionReturn<T>} action The action function
* @param {() => T} [fn] A function that returns the argument for the action
* @returns {Attachment<E>}
* @since 5.32 * @since 5.32
*/ */
export function fromAction(action, /** @type {() => any} */ get_arg = noop) { export function fromAction(action, fn = /** @type {() => T} */ (noop)) {
return (element) => { return (element) => {
const { update, destroy } = untrack(() => action(element, get_arg()) ?? {}); const { update, destroy } = untrack(() => action(element, fn()) ?? {});
if (update) { if (update) {
var ran = false; var ran = false;
render_effect(() => { render_effect(() => {
const arg = get_arg(); const arg = fn();
if (ran) update(arg); if (ran) update(arg);
}); });
ran = true; ran = true;

@ -11,18 +11,4 @@ export interface Attachment<T extends EventTarget = Element> {
(element: T): void | (() => void); (element: T): void | (() => void);
} }
export interface FromAction<Element extends EventTarget = HTMLElement, Par = unknown> {
<Node extends Element, Parameter extends Par>(
...args: undefined extends NoInfer<Parameter>
? [
action: (node: Node, parameter?: never) => void | ActionReturn<Parameter>,
parameter?: () => NoInfer<Parameter>
]
: [
action: (node: Node, parameter: Parameter) => void | ActionReturn<Parameter>,
parameter: () => NoInfer<Parameter>
]
): Attachment<Node>;
}
export * from './index.js'; export * from './index.js';

@ -625,7 +625,7 @@ declare module 'svelte/animate' {
} }
declare module 'svelte/attachments' { declare module 'svelte/attachments' {
import type { ActionReturn } from 'svelte/action'; import type { ActionReturn, Action } from 'svelte/action';
/** /**
* An [attachment](https://svelte.dev/docs/svelte/@attach) is a function that runs when an element is mounted * An [attachment](https://svelte.dev/docs/svelte/@attach) is a function that runs when an element is mounted
* to the DOM, and optionally returns a function that is called when the element is later removed. * to the DOM, and optionally returns a function that is called when the element is later removed.
@ -636,20 +636,6 @@ declare module 'svelte/attachments' {
export interface Attachment<T extends EventTarget = Element> { export interface Attachment<T extends EventTarget = Element> {
(element: T): void | (() => void); (element: T): void | (() => void);
} }
export interface FromAction<Element extends EventTarget = HTMLElement, Par = unknown> {
<Node extends Element, Parameter extends Par>(
...args: undefined extends NoInfer<Parameter>
? [
action: (node: Node, parameter?: never) => void | ActionReturn<Parameter>,
parameter?: () => NoInfer<Parameter>
]
: [
action: (node: Node, parameter: Parameter) => void | ActionReturn<Parameter>,
parameter: () => NoInfer<Parameter>
]
): Attachment<Node>;
}
/** /**
* Creates an object key that will be recognised as an attachment when the object is spread onto an element, * 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 * as a programmatic alternative to using `{@attach ...}`. This can be useful for library authors, though
@ -673,49 +659,18 @@ declare module 'svelte/attachments' {
* @since 5.29 * @since 5.29
*/ */
export function createAttachmentKey(): symbol; export function createAttachmentKey(): symbol;
export function fromAction<Node extends HTMLElement, Parameter extends any>(...args: undefined extends NoInfer<Parameter> ? [action: (node: Node, parameter?: never) => void | ActionReturn_1<Parameter, Record<never, any>>, parameter?: (() => NoInfer<Parameter>) | undefined] : [action: (node: Node, parameter: Parameter) => void | ActionReturn_1<Parameter, Record<never, any>>, parameter: () => NoInfer<Parameter>]): Attachment<Node>;
/** /**
* Actions can return an object containing the two properties defined in this interface. Both are optional. * Converts an Action into an Attachment keeping the same behavior. It's useful if you want to start using
* - update: An action can have a parameter. This method will be called whenever that parameter changes, * attachments on Components but you have library provided actions.
* immediately after Svelte has applied updates to the markup. `ActionReturn` and `ActionReturn<undefined>` both
* mean that the action accepts no parameters.
* - destroy: Method that is called after the element is unmounted
*
* Additionally, you can specify which additional attributes and events the action enables on the applied element.
* This applies to TypeScript typings only and has no effect at runtime.
* *
* Example usage: * Note that the second argument, if provided, must be a function that _returns_ the argument to the
* ```ts * action function, not the argument itself.
* interface Attributes {
* newprop?: string;
* 'on:event': (e: CustomEvent<boolean>) => void;
* }
* *
* export function myAction(node: HTMLElement, parameter: Parameter): ActionReturn<Parameter, Attributes> { * @param action The action function
* // ... * @param fn A function that returns the argument for the action
* return { * @since 5.32
* update: (updatedParameter) => {...},
* destroy: () => {...}
* };
* }
* ```
*/ */
interface ActionReturn_1< export function fromAction<E extends EventTarget, T extends unknown>(action: Action<E, T> | ((arg0: E, arg1: T) => void | ActionReturn<T>), fn?: (() => T) | undefined): Attachment<E>;
Parameter = undefined,
Attributes extends Record<string, any> = Record<never, any>
> {
update?: (parameter: Parameter) => void;
destroy?: () => void;
/**
* ### DO NOT USE THIS
* This exists solely for type-checking and has no effect at runtime.
* Set this through the `Attributes` generic instead.
*/
$$_attributes?: Attributes;
}
// Implementation notes:
// - undefined extends X instead of X extends undefined makes this work better with both strict and nonstrict mode
export {}; export {};
} }

Loading…
Cancel
Save