-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Portal #3088
Comments
#1849 ? |
@maxmilton How about event-bubbling-through-portals ? |
no, that case for Svelte2 |
Hi there, here's how you can do it: <script>
// src/components/Portal.svelte
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> |
nice answer,thx a lot |
What is the purpose of the wrapping 'portal' element? Just curious. Could be:
No? |
For some reason, when the container doesn't include the previously added element, I will have the error:
when using my version. This error doesn't happen using @ThomasJuster 's solution |
A better version of @ThomasJuster 's solution (in TypeScript though) with SvelteKit: <!-- components/Portal.svelte -->
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
export let target: HTMLElement | null | undefined = globalThis.document?.body;
let ref: HTMLElement;
onMount(() => {
if (target) {
target.appendChild(ref);
}
})
// this block is almost needless/useless (if not totally) as, on destroy, the ref will no longer exist/be in the DOM anyways
onDestroy(() => {
setTimeout(() => {
if (ref?.parentNode) {
ref.parentNode?.removeChild(ref);
}
})
})
</script>
<div bind:this={ref}>
<slot />
</div> And use it like so: <!-- route.svelte -->
<script lang='ts'>
import Portal from '../components/Portal.svelte';
let displayPortal = false;
</script>
{#if displayPortal}
<Portal>
This is a portal (content). Do some inspection in dev tools to see its (new) position! :)
</Portal>
{/if}
<button on:click={() => displayPortal = !displayPortal}>
Toggle Portal
</button> PS. @thojanssens This solution also fixes that: #3088 (comment) |
Excellent solution, works very well 😄 |
I am using SvelteKit and found an issue with this onDestroy(() => {
let _ref = ref;
setTimeout(() => {
if (_ref?.parentNode) {
_ref.parentNode?.removeChild(_ref);
}
})
}) |
is there some thing like
ReactDOM.createPortal(child, container)
in svelte3 ?The text was updated successfully, but these errors were encountered: