mirror of
https://github.com/yewstack/yew.git
synced 2025-12-08 21:26:25 +00:00
* 0.20 Changelog * Improve changelog generator * Add blog post * Add blog post * Apply suggestions from code review Co-authored-by: WorldSEnder <WorldSEnder@users.noreply.github.com> Co-authored-by: Julius Lungys <32368314+voidpumpkin@users.noreply.github.com> * update Changelog * update Cargo.toml * changelog gen compiles * website version 0.20 * add migration guides * prettier * i18n Co-authored-by: WorldSEnder <WorldSEnder@users.noreply.github.com> Co-authored-by: Julius Lungys <32368314+voidpumpkin@users.noreply.github.com>
65 lines
2.4 KiB
Plaintext
65 lines
2.4 KiB
Plaintext
---
|
|
title: 'Portals'
|
|
description: 'Rendering into out-of-tree DOM nodes'
|
|
---
|
|
|
|
## What is a portal?
|
|
|
|
Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.
|
|
`yew::create_portal(child, host)` returns a `Html` value that renders `child` not hierarchically under its parent component,
|
|
but as a child of the `host` element.
|
|
|
|
## Usage
|
|
|
|
Typical uses of portals can include modal dialogs and hovercards, as well as more technical applications
|
|
such as controlling the contents of an element's
|
|
[`shadowRoot`](https://developer.mozilla.org/en-US/docs/Web/API/Element/shadowRoot), appending
|
|
stylesheets to the surrounding document's `<head>` and collecting referenced elements inside a
|
|
central `<defs>` element of an `<svg>`.
|
|
|
|
Note that `yew::create_portal` is a low-level building block. Libraries should use it to implement
|
|
higher-level APIs which can then be consumed by applications. For example, here is a
|
|
simple modal dialogue that renders its `children` into an element outside `yew`'s control,
|
|
identified by the `id="modal_host"`.
|
|
|
|
```rust
|
|
use yew::prelude::*;
|
|
|
|
#[derive(Properties, PartialEq)]
|
|
pub struct ModalProps {
|
|
#[prop_or_default]
|
|
pub children: Children,
|
|
}
|
|
|
|
#[function_component]
|
|
fn Modal(props: &ModalProps) -> Html {
|
|
let modal_host = gloo::utils::document()
|
|
.get_element_by_id("modal_host")
|
|
.expect("Expected to find a #modal_host element");
|
|
|
|
create_portal(
|
|
html!{ {for props.children.iter()} },
|
|
modal_host.into(),
|
|
)
|
|
}
|
|
```
|
|
|
|
## Event handling
|
|
|
|
Events emitted on elements inside portals follow the virtual DOM when bubbling up. That is,
|
|
if a portal is rendered as the child of an element, then an event listener on that element
|
|
will catch events dispatched from inside the portal, even if the portal renders its contents
|
|
in an unrelated location in the actual DOM.
|
|
|
|
This allows developers to be oblivious of whether a component they consume, is implemented with
|
|
or without portals. Events fired on its children will bubble up regardless.
|
|
|
|
A known issue is that events from portals into **closed** shadow roots will be dispatched twice,
|
|
once targeting the element inside the shadow root and once targeting the host element itself. Keep
|
|
in mind that **open** shadow roots work fine. If this impacts you, feel free to open a bug report
|
|
about it.
|
|
|
|
## Further reading
|
|
|
|
- [Portals example](https://github.com/yewstack/yew/tree/master/examples/portals)
|