Skip to content

Commit 37b1121

Browse files
committed
Added body portal class.
1 parent aa7e96e commit 37b1121

1 file changed

Lines changed: 44 additions & 0 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#pragma once
2+
3+
#include <nui/frontend/element_renderer.hpp>
4+
#include <nui/frontend/dom/element.hpp>
5+
6+
#include <memory>
7+
8+
namespace Nui
9+
{
10+
/**
11+
* @brief RAII wrapper that renders an ElementRenderer into a detached DOM
12+
* element and appends it directly to document.body, bypassing any CSS
13+
* transform / filter / perspective containment on ancestor elements in the
14+
* Nui component tree. Useful for overlays (menus, tooltips, modals) that
15+
* rely on viewport-relative positioning (position:fixed).
16+
*
17+
* The element is removed from the DOM when the BodyPortal is destroyed.
18+
* BodyPortal is non-copyable but move-constructible.
19+
*/
20+
class BodyPortal
21+
{
22+
public:
23+
explicit BodyPortal(Nui::ElementRenderer renderer)
24+
: element_{Dom::Element::makeElement(HtmlElement{"div", &RegularHtmlElementBridge})}
25+
{
26+
element_->replaceElement(std::move(renderer));
27+
Nui::val::global("document")["body"].call<void>("appendChild", element_->val());
28+
}
29+
30+
BodyPortal(BodyPortal const&) = delete;
31+
BodyPortal& operator=(BodyPortal const&) = delete;
32+
BodyPortal(BodyPortal&&) = default;
33+
BodyPortal& operator=(BodyPortal&&) = default;
34+
35+
~BodyPortal()
36+
{
37+
if (element_)
38+
element_->val().call<void>("remove");
39+
}
40+
41+
private:
42+
std::shared_ptr<Dom::Element> element_;
43+
};
44+
}

0 commit comments

Comments
 (0)