0

In case I have multiple <slot />s nested inside my Stencil component, I would need to give them names, and then reference them inside my HTML page when using that component. So, how do I do that?

Example:

  render() {
    return(
      <div>
        <button><slot name="one" /></button>
        <select>
          <option value="one"><slot name="two" /></option>
        </select>
        <p> <slot name="three" /></p>
      </div>
    )
  }

And then when I am adding this component, how do I add content to each <slot />?

I have tried what is explained here: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot but it's not working! I have tried the following in my HTML page:

<span slot="two">dfdf</span> 
<slot name="two"><span>gdgdg</span></slot> 

Neither work!

happy_story
  • 1
  • 1
  • 7
  • 17

1 Answers1

0

The example in the MDN documentation is about as clear as you can get.
I only deleted content from the example <template> to focus on just the <slot> elements:

customElements.define("slot-example", class extends HTMLElement{
  constructor(){
    super()
     .attachShadow({mode:"open"})
     .append(document.getElementById(this.nodeName).content.cloneNode(true));
  }
});
<template id="SLOT-EXAMPLE">
  <style>span { color:red }</style>
  <slot name="element-name">NEED NAME</slot>
  <span><slot name="description">NEED DESCRIPTION</slot></span>
  <slot name="attributes"><p>None</p></slot>
</template>

<slot-example>
  <span slot="element-name">slot-example</span>
  <span slot="description">This demonstrates slot</span>
</slot-example>

<slot-example>
  <b slot="element-name">another slot-example</b>
  <b slot="attributes">Explain to yourself why this is bold and not a paragraph</slot>
</slot-example>

For a deep, deep, very deep dive into styling slots with ::slotted see: ::slotted CSS selector for nested children in shadowDOM slot

Addition after comments

Here some inspiration to get you started:

customElements.define("my-select", class extends HTMLElement{
  connectedCallback(){
    setTimeout(()=>{ // ! wait till innerHTML is parsed
      this.innerHTML = 
          "<SELECT>" + 
          this.innerHTML
              .split("\n")
              .filter(Boolean)
              .map(company=>`<OPTION>${company.trim()}</OPTION>`);
          "</SELECT>";
    });
  }
});
<my-select>
Apple
Microsoft
Google
Mozilla
</my-select>
Danny '365CSI' Engelman
  • 16,526
  • 2
  • 32
  • 49
  • I'm sorry but how is that different from what I did? The only difference is that my web components are made in Stencil, where as you are doing them with JS. Also, you are adding the slots in Vue, and I am adding them in HTML. I have heard that you cannot name slots in the light DOM, but only in the shadow DOM. So that could explain why is it not working for me. – happy_story Jan 13 '23 at 12:43
  • ???!!! This **is** native JS and HTML code, not Vue. You _name_ SLOTs in shadowDOM with the ``name`` attribute, you _target/assign_ SLOTs in lightDOM with the ``slot`` attribute – Danny '365CSI' Engelman Jan 13 '23 at 13:02
  • I just discovered that the issue is the element I am trying to put a slot in. Naming slots work, but not in `` for some reason. – happy_story Jan 13 '23 at 13:15
  • Ah! Yes, `` – Danny '365CSI' Engelman Jan 13 '23 at 14:04
  • But my is inside the ` inside ` – happy_story Jan 13 '23 at 14:22
  • Just to be clear, ` – happy_story Jan 13 '23 at 14:28
  • You can't use ``slot`` on or inside `` – Danny '365CSI' Engelman Jan 13 '23 at 15:05
  • Okay.. So, what do I do then? How can I do it? Is creating a custom dropdown/select the only solution? – happy_story Jan 13 '23 at 15:10
  • or built the whole ``SELECT`` and ``OPTION`` Children **HTML** yourself; – Danny '365CSI' Engelman Jan 13 '23 at 15:12
  • Okay, last question. How do I add a class now to the slotted element? I understand that you can't have a `class` on the . So, if I pass ` – happy_story Jan 13 '23 at 15:37
  • Make it a new question, and include a working SO snippet (that [<>] button in the SO editor) – Danny '365CSI' Engelman Jan 13 '23 at 17:06
  • I posted a new question, please take a look: https://stackoverflow.com/questions/75131443/how-do-i-add-a-class-to-a-slotted-element – happy_story Jan 16 '23 at 07:51