Search code examples
sveltesapper

Append svelte component to another component, depending on the viewport width


There are 3 components - A, B, C. C component is in A.

If viewport width smaller then x px need to remove C component into B.

Its easy to do with vanilla js. Is it possible to do in svelte without creating two C components ?

vanilla-js-example - <https://codepen.io/vladbelozertsev/pen/eYzoYmO?editors=1111>


Solution

  • No there isn't really an officially supported way / construct to do that. In Svelte, the only case where a component moves in the tree is with keyed lists:

    {#each items as item}
      <MyComponent key={item.id}>{item.text}</MyComponent>
    {/each}
    

    There's been some discussion about portals, and even a lib.

    Otherwise you can still implement something like this yourself, by using the DOM API to move the elements in a Svelte component yourself.

    Bellow is an example that moves "a component" (really, the elements of the component -- the component itself stays in the same place in the virtual Svelte component tree) -- REPL.

    Child.svelte

    <div>I am Child</div>
    

    App.svelte

    <script>
        import Child from './Child.svelte'
        
        let wrapper
        let left
        let right
        
        const goLeft = () => {
            left.appendChild(wrapper)
        }
        
        const goRight = () => {
            right.appendChild(wrapper)
        }
    </script>
    
    <button on:click={goLeft}>Left</button>
    
    <button on:click={goRight}>Right</button>
    
    <div>
        <div class="container left" bind:this={left} />
        <div class="container right" bind:this={right} />
    </div>
    
    <div bind:this={wrapper}>
        <Child />
    </div>