Skip to content

Conditionally add a wrapper/parent tag #7528

Closed
@acarl005

Description

@acarl005

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions