<Teleport> is a built-in component that allows us to "teleport" a part of a component's template into a DOM node that exists outside the DOM hierarchy of that component.
...
Sometimes we may run into the following scenario: a part of a component's template belongs to it logically, but from a visual standpoint, it should be displayed somewhere else in the DOM
The following SlintPad example demonstrates how such functionality would be useful to prevent undesired overlaps of spacial component extensions (sometimes also seen in the form of a glow effect to indicate focus):
component HoverHighlightText {
in property <string> text;
//in property <component-ref> teleport-highlight-to: parent;
Rectangle {
// Every element gets this new property, which only
// affects the z-order and possible clipping.
// Teleported elements should probably be placed on top of
// regular elements inside their container.
// It could also be named `teleportation-target`, which
// would be quite verbose, though.
//teleport-to: root.teleport-highlight-to;
property <length> extension: 6px;
x: t.x - self.extension;
y: t.y - self.extension;
width: t.width + 2 * self.extension;
height: t.height + 2 * self.extension;
border-radius: self.extension / 1.6;
background: ta.has-hover ? lightgray : transparent;
}
ta := TouchArea {
t := Text {
text: root.text;
}
}
}
export component Demo {
width: 200px;
height: 200px;
VerticalLayout {
alignment: start;
HoverHighlightText {
text: "Foo";
//teleport-highlight-to: root;
}
HoverHighlightText {
text: "Bar";
//teleport-highlight-to: root;
}
HoverHighlightText {
text: "Baz";
//teleport-highlight-to: root;
}
HoverHighlightText {
text: "Qux";
//teleport-highlight-to: root;
}
}
}
This video demonstrates the problem. Pay attention to the highlight overlapping some text, although these highlights should always be in the background surface:
Vue.js has
<Teleport>
:The following SlintPad example demonstrates how such functionality would be useful to prevent undesired overlaps of spacial component extensions (sometimes also seen in the form of a glow effect to indicate focus):
This video demonstrates the problem. Pay attention to the highlight overlapping some text, although these highlights should always be in the background surface:
https://github.com/user-attachments/assets/da343caf-46a9-4b28-bec5-130a7c2f8e05
Of course, you can flatten your component hierarchy to work around this. But good encapsulation and separation of concerns should be possible.
I had to use the non-existent type
component-ref
. Related issues regarding this: #5082, #2390.