Reputation: 862
I want to make a web component from a <select>
Element. I'm trying to get the <option>
tags supplied by the user to appear in the Shadow DOM.
My component:
let tmpl = document.createElement('template');
tmpl.innerHTML = `
<select placeholder="text">
<slot name="option"></slot>
</select>
`;
class SelectBox extends HTMLElement {
constructor() {
super();
if (!this.shadowRoot) {
this.root = this.attachShadow({mode: 'open'});
this.root.appendChild(tmpl.content.cloneNode(true));
}
}
}
customElements.define('select-box', SelectBox);
HTML:
<select-box>
<option slot="option" value="text">text</option>
</select-box>
What's being rendered is an empty select box. I can see in the console that the element is empty
Which leads me to believe I haven't grasped the process of inserting user elements into the shadow DOM.
Upvotes: 3
Views: 1722
Reputation: 3198
It looks like the problem is the option
element that cannot be assigned as slot.
However, since your template is just a select, I wonder why you are not simply extending a select instead and call it a day.
class SelectBox extends HTMLSelectElement {
connectedCallback() {
// in case is not fully parsed yet ...
if (this.selectedIndex < 0)
return setTimeout(() => this.connectedCallback());
this.addEventListener('change', this);
this.parentNode.insertBefore(
document.createElement('p'),
this.nextSibling
);
this.handleEvent();
}
handleEvent() {
this.nextSibling.textContent =
`${this.selectedIndex}: ${this.value}`;
}
}
customElements.define('select-box', SelectBox, {extends: 'select'});
With above class all you need is just the DOM with your options, and you were putting options where these didn't belong anyway, just go full built-in extend.
<select is="select-box">
<option value="first">first</option>
<option value="second">second</option>
</select>
You can see it working live in this code pen.
The less than 1k polyfill and the rest is described in this medium post.
I know this didn't exactly solve your issue, but unless you want to wait for all browsers to fix that at least you know there is a standard/better way to extend built-ins.
Upvotes: 5