javascript - Använda slots i WebComponents utan att använda shadow DOM
Jag försöker bygga en WebComponent utan att använda ShadowDOM - hittills har det mestadels fungerat, men nu vill jag bygga en komponent som omsluter andra komponenter precis som man skulle göra med Angulars @ViewChild/@ViewChildren. (biblioteket jag använder här för att rendera är uhtml, liknande lit-html)
export class Dropdown extends HTMLElement {
private open: boolean = false;
static observedAttributes = ["open"]
constructor() {
super();
}
attributeChangedCallback(name: string, oldValue: string, newValue: string) {
switch (name) {
case "open":
this.open = Boolean(newValue);
break;
}
this.display()
}
connectedCallback() {
this.display()
}
display = () => {
render(this, html`
<div>
<slot name="item">
</slot>
</div>
`)
}
static register = () => customElements.define("my-dropdown", Dropdown)
}
Om jag nu använder denna komponent
Dropdown.register();
render(document.body, html`
<my-dropdown open="true">
<strong slot="item">test</strong>
</my-dropdown>
`)
Jag förväntar mig att se
<my-dropdown>
<div>
<strong>test</test>
</div>
</my-dropdown>
men slottdelen fungerar inte.
Om jag byter till ShadowDOM fungerar det bara, men nu måste jag hantera ShadowDOM:s sandlåda när det gäller styling, vilket jag helst inte vill göra.
constructor() {
super();
this.attachShadow({mode: "open"})
}
display = () => {
render(this.shadowRoot as Node, html`
Är det möjligt att få slots att fungera utan shadowDOM? Om inte, finns det ett annat sätt att hämta innehållet som definierats inuti komponenten och använda det i visningen?
<my-component>
<div>some content here</div>
</my-component>
bör renderas som
<my-component>
<header>
random header
</header>
<section>
<!-- my custom content -->
<div>some content here</div>
</section>
</my-component>
Några förslag?
Svar #1
Nej, <slot> är en del av shadowDOM API:et
Du kan fejka det, men eftersom det inte finns något shadowDOM skulle du behöva lagra det innehållet någon annanstans.
Det kan vara en <template> som du läser och analyserar ditt (lätta)DOM-innehåll i.
Det där är en j*vla massa DOM-mutationer.
Det kan vara lättare att bara lära sig att styla shadowDOM med:
- CSS-egenskaper
- ärvbara stilar
- ::slotted
- ::del
- konstruerbara stilmallar