Skip to content

Partial components #16173

Open
Feature
@jjagielka

Description

@jjagielka

Describe the bug

Components in Svelte 5 are functions so it should be pretty straight forward to make a curried (partial) component (with some props pre-populated).

Doing the below implementation works perfectly for the component creation. However the partial components do not react for props changes (change the size in the input).

Where is the problem?

<!-- Button.svelte -->
<script>
    let { children, color, size } = $props();
</script>

<button style:border-width={size + "px"} style:border-color={color}>{@render children()}</button>
// buttons.ts
import type { Component, ComponentInternals, ComponentProps } from "svelte";
import Button from "./Button.svelte"

function partial<T extends Component<any>>(component: T, partialProps: Partial<ComponentProps<T>>) {
    return (anchor: ComponentInternals, props: ComponentProps<T>) => {
        return component(anchor, { ...partialProps, ...props })
    }
}

export const GreenButton = partial(Button, {color: 'green'});
export const RedButton = partial(Button, {color: 'red'});

then

<script>
<script lang="ts">
    import Button from "./Button.svelte";
    import { RedButton, GreenButton } from "./buttons";

    let size = $state(4);
</script>

<Button color="blue" {size}>White</Button>
<Button color="green" {size}>Green</Button>
<Button color="red" {size}>Red</Button>
<RedButton {size}>Red button</RedButton>
<GreenButton {size}>Green button</GreenButton>
<input bind:value={size} />

</script>

Reproduction

https://svelte.dev/playground/88ba3c73bba646da95a3d11082c3a05c?version=latest

Logs

System Info

System:
    OS: Linux 6.14 Arch Linux
    CPU: (8) x64 11th Gen Intel(R) Core(TM) i7-11390H @ 3.40GHz
    Memory: 17.90 GB / 31.08 GB
    Container: Yes
    Shell: 5.9 - /usr/bin/zsh
  Binaries:
    Node: 24.1.0 - /usr/bin/node
    Yarn: 1.22.22 - /usr/bin/yarn
    npm: 11.4.1 - /usr/bin/npm
    pnpm: 10.11.1 - /usr/bin/pnpm
  Browsers:
    Chromium: 137.0.7151.68
  npmPackages:
    svelte: ^5.33.19 => 5.33.19

Severity

annoyance

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions