I\'m currently experimenting with StencilJS to create some web components.
Now I know that there is
and named slots and all that stuff. Comin
Thank you for the answer Gil.
I was thinking of something similar before (setting state etc. - because of timing issues that might come up). I didn't like the solution though, because you're then doing a state change within componentDidLoad, which will trigger another load just after the component did load. This seems dirty and unperfomant.
The little bit with innerHTML={child.outerHTML}
helped me alot though.
It seems like you can also simply do:
import {Component, Element, State} from '@stencil/core';
@Component({
tag: 'slotted-element',
styleUrl: 'slotted-element.css',
shadow: true
})
export class SlottedElement {
@Element() host: HTMLDivElement;
render() {
return (
{Array.from(this.host.children)
.map(child => )}
);
}
}
I thought you might run into timing issues, because during render()
the child elements of the host have already been removed to make space for whatever render()
returns. But since shadow-dom and light-dom coexist nicely within the host component, I guess there shouldn't be any issues.
I don't really know why you have to use innerHTML
though. Coming from React I'm used to doing:
{Array.from(this.host.children)
.map(child => - {child}
)}
And I thought that is basic JSX syntax and that since Stencil is also using JSX I could do that, too. Doesn't work though. innerHTML
does the trick for me. Thanks again.
EDIT: The timing issues I mentioned will appear if you're not using shadow-dom though. Some strange things start to happen an you'll end up with a lot of duplicate children. Though you can do (might have side effects):
import {Component, Element, State} from '@stencil/core';
@Component({
tag: 'slotted-element',
styleUrl: 'slotted-element.css',
shadow: true
})
export class SlottedElement {
children: Element[];
@Element() host: HTMLDivElement;
componentWillLoad() {
this.children = Array.from(this.host.children);
this.host.innerHTML = '';
}
render() {
return (
{this.children.map(child => )}
);
}
}