Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spreading with this attribute: <svelte:element> must have a 'this' attribute with a value #12662

Open
kutoman opened this issue Jul 30, 2024 · 2 comments
Labels
awaiting submitter needs a reproduction, or clarification

Comments

@kutoman
Copy link

kutoman commented Jul 30, 2024

Describe the bug

When we set the this attribute of svelte:element explicitly via an object containing the this attribute, everything is as expected.
But when we spread that object in the svelte:element component the compiler does not consider that this attribute.

Reproduction

https://stackblitz.com/edit/vitejs-vite-w8nmej?file=src%2FApp.svelte

Logs

No response

System Info

skipping this as it is happening everywhere, like in stackblitz

Severity

annoyance

@kutoman kutoman changed the title spreading with this attribute: <svelte:element> must have a 'this' attribute with a value spreading with this attribute: <svelte:element> must have a 'this' attribute with a value Jul 30, 2024
@dummdidumm
Copy link
Member

This works as expected - the this attribute needs to be set statically (the compiler error is correct).

Question is whether or not it is possible to relax this constraint. Why is this important to you? I imagine this being rather easy to work around.

@dummdidumm dummdidumm added the awaiting submitter needs a reproduction, or clarification label Jul 30, 2024
@kutoman
Copy link
Author

kutoman commented Jul 30, 2024

Why is this important to you?

I'm working on a components library where I noticed a specific pattern regarding the case when I have to use svelte:element.
So I decided to share the logic between those components where I use svelte:element with a custom rune.

/**
 * Takes care of setting up svelte:element based on props for [CanBeLabel] properly
 * @param props 
 * @param defaultTag tag to be used in default cases
 * @returns props to be spread on svelte:element
 */
export function createCanBeLabel<T extends string>(labelId: string|undefined, defaultTag: T): { ['this']: T|'label', for: U<string> } {
    const tag = $derived(labelId? 'label' : defaultTag);
    return { 
        get ['this']() { return tag }, 
        get for() { return labelId }
    };
}

The rune decides when to use a label tag and sets the necssary additional attributes (e.g. for) accordingly.
Since I am used to use the spread operator in Svelte components, which is really great, I just thought it makes sense to use it in this case also. Therefore I intuitively tried:

<script lang="ts">
...
</script>
<svelte:element {...createCanBeLabel(labelId, 'div')}>
    {@render props.children()}
</svelte:element>

but I have to do instead:

<script lang="ts">
...
    const _ = createCanBeLabel(labelId, 'div');

</script>
<svelte:element this={_.this} for={_.for}>
    {@render props.children()}
</svelte:element>

Yes this seems like a straightforward workaround but it is a bit more error prone since the usage of the shared behavior (rune) only makes sense when all attributes are passed to svelte:element without missing any. Please note: it's not just for a single component.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting submitter needs a reproduction, or clarification
Projects
None yet
Development

No branches or pull requests

2 participants