I'm currently diving into Webcomponents with Litelements: In Webcomponents you can change the way the shadowdom works by defining the mode property as 'open' or 'closed'. Like this in vanilla Javascript without LitElements:
Javascript:
var shadow = this.attachShadow({mode: 'open'});
from: https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow
Now in Litelements with Typescript this is achieved like this:
Typescript:
export class MyWebcomponents extends LitElement {
static shadowRootOptions = {...LitElement.shadowRootOptions, delegatesFocus: true};
}
from: https://lit.dev/docs/components/shadow-dom/
he simplest way to customize the render root is to set the shadowRootOptions static property. The default implementation of createRenderRoot passes shadowRootOptions as the options argument to attachShadow when creating the component's shadow root. It can be set to customize any options allowed in the ShadowRootInit dictionary, for example mode and delegatesFocus.
To be honest, I was not able to get this to work, I tried a lot of things, like this:
Typescript:
static shadowRootOptions = {...{mode: 'open'}, delegatesFocus: true};
The upper try gives me an error that I'm not correctly extending the class LitElement.
Typescript:
static shadowRootOptions = {mode: 'open', delegatesFocus: true};
Gives me silly errormessage only VS Code and Typescript can produce boils down to wrong class extensions as well.
Typescript:
static shadowRootOptions = {{mode: 'open'}, delegatesFocus: true};
The upper try gives me a message telling me that Im not extending correctly and also moans about syntax.
I then tried to find out what type LitElement.shadowRootOptions is and provide something similar, but then I got into a rabbit hole of raising more questions and find this simple oneliner even more obscure. ( Yes I did read into the the spread syntax, and I think I understand it, I also read this posts according spread syntax: I don't understand about spread syntax inside objects and Is it spread "syntax" or the spread "operator"? )
So for the sake of keeping this question simple:
Can anybody point me into the right direction on how I have to write the syntax so this does work? I just want to be able to set the mode to open or close in the way its ment to be set.
Thanks a lot!
Greetings
Alex
By default lit element is acting in mode open
.
So customLitElement.shadowRoot
returns a shadow-root.
If you want to run it in closed mode set the options as follows:
static shadowRootOptions = {...LitElement.shadowRootOptions, mode: 'closed', delegatesFocus: true};
<script type="module">
import {
LitElement,
html,
css
} from "https://unpkg.com/lit-element/lit-element.js?module";
class ClosedEl extends LitElement {
static shadowRootOptions = {...LitElement.shadowRootOptions, mode: 'closed', delegatesFocus: true};
render() {
return html`
<h1>Example Closed</h1>
`;
}
}
class OpenedEl extends LitElement {
render() {
return html`
<h1>Example Opened</h1>
`;
}
}
customElements.define("my-closed", ClosedEl);
customElements.define("my-opened", OpenedEl);
console.log(`ShadowRoot of closed El: ${document.getElementById('closed').shadowRoot}`);
console.log(`ShadowRoot of opened El: ${document.getElementById('opened').shadowRoot}`);
console.log(`Access to opened El: ${document.getElementById('opened').shadowRoot.innerHTML}`);
</script>
<my-closed id="closed"></my-closed>
<my-opened id="opened"></my-opened>
To proove, that a shadow dom is of course created, here a screenshot: