Description
Describe the problem
Hello. I have situations where I sometimes want to add a wrapping <div>
around some other tag based on a conditional. Currently, I'm doing something like this in my component as a workaround:
{#if needs_div_wrapper}
<div class="wrapper">
<p class="lots-of-content">...</p>
</div>
{:else}
<p class="lots-of-content">...</p>
{/if}
Notice I had to write <p class="lots-of-content">...</p>
twice. That isn't too bad in this example, but in my real scenario I have a HUGE component tree, hence a lot of of duplicated code. I could create another component for that content to minimize the repetition. However, the content is coupled to a lot of props and state in that component, and I don't want to have to pass through a bunch of state, props, and event-handling functions into a new component. It also feels inappropriate to be creating new component files basically just for the purpose of 1 conditional for a tag, which seems like it should be taken care of by the template language.
Describe the proposed solution
Something like this has been proposed before (#3913), though it was stated that the proposal is not acceptable...
{#if needs_div_wrapper}
<div>
{/if}
<a>My static content!</a>
{#if needs_div_wrapper}
</div>
{/if}
Also discussed a bit on stackoverflow.
I will propose other alternatives.
A special svelte attribute?
<div class="wrapper" svelte:if={needs_div_wrapper}>
<p class="lots-of-content">...</p>
</div>
Something like svelte:if
could remove the element/component from the DOM tree and replace it by its children.
As @Conduitry has pointed out...
"Svelte needs to know about the structure of the component at compile time"
So, maybe this solution could just be implemented as mere syntactic sugar for my first example demonstrating the WETness?
Another proposal could be some kind of no-op element.
No-op value to <svelte:element>
<script>
let wrapper = needs_div_wrapper ? "div" : null
</script>
<svelte:element this={wrapper} class="wrapper">
<p class="lots-of-content">...</p>
<svelte:element>
<svelte:element>
can simply be removed if you pass null
(or some other sentinel value) to this
.
Or maybe the <svelte:element>
could become something like a <svelte:fragment>
under a conditional?
Alternatives considered
As of now, I'm just doing what I described above where I need to specify the child element tree twice in the 2 branches of an if
block. Would be nice to have 1 of the proposed solutions to DRY things up!
Importance
would make my life easier