diff --git a/.changeset/itchy-planets-hang.md b/.changeset/itchy-planets-hang.md new file mode 100644 index 000000000000..c3490041ca93 --- /dev/null +++ b/.changeset/itchy-planets-hang.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +feat: add possibility to decorate components diff --git a/packages/svelte/src/index-client.js b/packages/svelte/src/index-client.js index b4f5e9a12b68..23548a144787 100644 --- a/packages/svelte/src/index-client.js +++ b/packages/svelte/src/index-client.js @@ -180,6 +180,26 @@ export function flushSync(fn) { flush_sync(fn); } +/** + * Wraps a component with a decorator that is able to modify the props of the component before it is created. + * @template {import('svelte').SvelteComponent} Component + * @template {import('svelte').ComponentProps} [Props=import('svelte').ComponentProps] + * @param {Component} component + * @param {(args: { props: Props, component: (props: Props) => Component }) => Component} decorator + * @returns {Component} + */ +export function decorateComponent(component, decorator) { + // @ts-expect-error shape is different under the hood + return (target, props) => { + return decorator({ + props, + component: (props) => + // @ts-expect-error shape is different under the hood + component(target, props) + }); + }; +} + export { hydrate, mount, unmount } from './internal/client/render.js'; export { diff --git a/packages/svelte/src/index-server.js b/packages/svelte/src/index-server.js index 5bcb13e5f2ef..b662a3e0e686 100644 --- a/packages/svelte/src/index-server.js +++ b/packages/svelte/src/index-server.js @@ -34,4 +34,23 @@ export function unmount() { export async function tick() {} +/** + * @template {import('svelte').SvelteComponent} Component + * @template {import('svelte').ComponentProps} [Props=import('svelte').ComponentProps] + * @param {Component} component + * @param {(args: { props: Props, component: (props: Props) => Component }) => Component} decorator + * @returns {Component} + */ +export function decorateComponent(component, decorator) { + // @ts-expect-error shape is different under the hood + return (payload, props) => { + return decorator({ + props, + component: (props) => + // @ts-expect-error shape is different under the hood + component(payload, props) + }); + }; +} + export { getAllContexts, getContext, hasContext, setContext } from './internal/server/context.js'; diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts index 3a26e79e91d7..0505751c413b 100644 --- a/packages/svelte/types/index.d.ts +++ b/packages/svelte/types/index.d.ts @@ -304,6 +304,13 @@ declare module 'svelte' { * Synchronously flushes any pending state changes and those that result from it. * */ export function flushSync(fn?: (() => void) | undefined): void; + /** + * Wraps a component with a decorator that is able to modify the props of the component before it is created. + * */ + export function decorateComponent, any, any>, Props extends ComponentProps = ComponentProps>(component: Component, decorator: (args: { + props: Props; + component: (props: Props) => Component; + }) => Component): Component; /** Anything except a function */ type NotFunction = T extends Function ? never : T; /**