Giter Club home page Giter Club logo

svelte-portal's Introduction

Svelte component for rendering outside the DOM of parent component

Idea borrowed from here: sveltejs/svelte#3088 (comment)

Installation

npm install --save svelte-portal

or

yarn add svelte-portal

Usage Portal component

The <Portal /> component has only one property: target

target can be a HTMLElement target={document.body} or a css selector target="#modals" that points to an already existing element.

When no target is given it defaults to: document.body.

Example

<script>
  import Portal from "svelte-portal";
</script>

<Portal target="body">
  <div class="toast">Entity successfully updated!</div>
</Portal>

Usage portal action

The functionality can also be applied to DOM elements directly via a svelte action:

Example

<script>
  import { portal } from "svelte-portal";
</script>

<div class="toast" use:portal={"body"} hidden>Entity successfully updated!</div>

The hidden atrribute is only needed when using ssr, when portal has moved the element to it's targetted location it removes the hidden attribute.

TypeScript support

<script lang="ts"> users should import from "svelte-portal/src/Portal.svelte" instead of "svelte-portal" to get typing support.

svelte-portal's People

Contributors

cbenz avatar dependabot-preview[bot] avatar dependabot[bot] avatar frederikhors avatar harshmandan avatar johannchopin avatar m93a avatar romkor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

svelte-portal's Issues

Type definitions missing

When I try to import the package in my Svelte project, I get the following error:

Could not find a declaration file for module 'svelte-portal'.
'node_modules/svelte-portal/src/main.cjs.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/svelte-portal` if it exists or add a new declaration (.d.ts) file containing `declare module 'svelte-portal';`

Looking at the svelte-portal folder in node_modules, there indeed isn't any .d.ts file.

This is weird, sveltekit package should produce both a compiled .svelte file as well as .d.ts file. (For comparison, projects like svelte-material-ui do ship the .d.ts files, and therefore work out-of-the-box.) Could you, by any chance, publish the package with the type definitions?

Changes in 2.2.1 caused import error when following the old documentation

The latest update should probably not have been a patch version bump. We were using import Portal from "svelte-portal/src/Portal.svelte"; like the documentation suggested. This caused builds to fail with this new version, even in projects that didn't directly import it. A patch gets applied even with a simple install command if you're using the widely accepted ^ for your versions. In our case this was ^2.2.0.

Now the version can't be changed anymore, but the documentation should be updated to not show broken code.

Cannot read properties of null (reading 'removeChild')

I'm using svelte-portal for a modal with a Create button. When Create is clicked, it goes to a new page which has a different __layout.svelte. When this happens, this error is thrown:

Uncaught TypeError: Cannot read properties of null (reading 'removeChild')
    at detach (index.mjs:373:21)
    at detach_dev (index.mjs:2004:5)
    at Object.destroy [as d] (Nav.svelte:139:8)
    at index.mjs:1141:27
    at run (index.mjs:18:12)
    at Array.forEach (<anonymous>)
    at run_all (index.mjs:24:9)
    at Object.c (index.mjs:1339:37)
    at index.mjs:175:19
    at Set.forEach (<anonymous>)

Element targets assume window context

The type check here assumes that the target element is in the same window context as the script:

https://github.com/romkor/svelte-portal/blob/master/src/Portal.svelte#L25

This might not always be the case, such as running across iframes or windows. See this StackOverflow answer: https://stackoverflow.com/a/26251098/3902950

Iframes have their own copy of HTMLElement, so target instanceof HTMLElement returns false, while target instanceof otherwindow.HTMLElement returns true.

Open to ideas on how this might be best implemented - perhaps with another optional property specifying the reference window?

  /**
   * Usage: <div use:portal={'css selector'}> or <div use:portal={document.body}> or <div use:portal={document.body} window={otherwindowcontext}>
   *
   * @param {HTMLElement} el
   * @param {HTMLElement|string} target DOM Element or CSS Selector
   * @param {Window} [window=window] Target window DOM document
   */

Update or replace?

I have a question, Portal adds new content to some element, but I would like to get replacing. I have a DOM element that can be shared among many <Portal> tags.

Is it possible that every new Portal render just replaces the content of the DOM element but not just adds there?

Fix warning while using with `vite-plugin-svelte`

While using the dep with @sveltejs/kit:v2.x setup, vite:v5.x and @sveltejs/vite-plugin-svelte:v3.0.0 on running the app a warning is displayed:

Please see https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/faq.md#missing-exports-condition for details.
[vite-plugin-svelte] WARNING: The following packages have a svelte field in their package.json but no exports condition for svelte.

[email protected]

Open portal on popup

Goal

I wan't to open a new window in popup mode and modify it's content via a svelte component, but it didn't work, with the error of the target isn't a HTMLElement or a selector

Example

Stackblitz link

Expected behaviour

Be possible to render a component inside an opened popup

use portal inside keyed_each block

Nice portal!

One limitation I find is when use inside a keyed_each block (as tooltip or dropdown), parent will be change back to original parent by svelte.

https://github.com/sveltejs/svelte/blob/master/src/runtime/internal/keyed_each.ts#L46

demo: https://svelte.dev/repl/4023593f8d324c7587824b2da4f01f1d?version=3.44.2

one hack solution is add a MutationObserver to original parent, on mutation event change back to portal target again.

Another issue is portal node have to be wrapped by a container, svelte will try to change order by Node.insertBefore, but the node already change parent, this will result to
DOMException: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.

I don't think there is a fix for this "issue", maybe add some note in README, so folks can be aware of the potential limitation

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.