Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implement a portal in Svelte

In React you can render a component in a different node using Portals:

ReactDOM.createPortal( 
  <Component />,
  document.getElementById('id')
);

Same for Vue using the portal-vue package.

But is there a way to something similar in Svelte?

<body>
  <Header>
    <Modal /> <!-- Modal is rendered here -->
  </Header>

<!-- But the Modal DOM would be injected at the body end -->
</body>
like image 835
johannchopin Avatar asked Jan 25 '23 22:01

johannchopin


1 Answers

See this issue : https://github.com/sveltejs/svelte/issues/3088

Portal.svelte

<script>
import { onMount, onDestroy } from 'svelte'
let ref
let portal

onMount(() => {
  portal = document.createElement('div')
  portal.className = 'portal'
  document.body.appendChild(portal)
  portal.appendChild(ref)
})

onDestroy(() => {
  document.body.removeChild(portal)
})

</script>

<div class="portal-clone">
  <div bind:this={ref}>
    <slot></slot>
  </div>
</div>
<style>
  .portal-clone { display: none; }
</style>

You can then you it with the following template. Modal will be renderer under <body/> :

<Portal>
  <Modal/>
</Portal>
like image 180
Jérémie B Avatar answered Feb 05 '23 09:02

Jérémie B