Search code examples
htmlweb-componentshadow-domcustom-element

How do I get web component slots to work?


I've copied MDN's example (https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_templates_and_slots) but don't get it to work here are my components:

<link rel="import" href="../molecules/main-menu__topbar.html">


<template id="main-menu">
  <p>I'M THE MENU ELEMENT</span>
  <main-menu__topbar></main-menu__topbar>
  <main-menu__topbar>
    <span slot="my-text">Let's have some different text!</span>
  </main-menu__topbar>

</template>

<script>
  (function() {
    var importDoc = document.currentScript.ownerDocument;

    var proto = Object.create(HTMLElement.prototype);

    proto.createdCallback = function() {

      var template = importDoc.querySelector('#main-menu');

      var clone = document.importNode(template.content, true);

      var root = this.createShadowRoot();
      root.appendChild(clone);
    };

    document.registerElement('main-menu', {prototype: proto});
  })();
</script>

and the imported topbar:

<template id="main-menu__topbar">
  <div class="main-menu__topbar">
    <p>I'm the topbar</p>
    <p><slot name="my-text">My default text</slot></p>
  </div>
</template>

<script>
  (function() {
    var importDoc = document.currentScript.ownerDocument;

    var proto = Object.create(HTMLElement.prototype);

    proto.createdCallback = function() {

      var template = importDoc.querySelector('#main-menu__topbar');

      var clone = document.importNode(template.content, true);

      var root = this.createShadowRoot();
      root.appendChild(clone);
    };

    document.registerElement('main-menu__topbar', {prototype: proto});
  })();
</script>

How do I get the second top bar within the menu to display "Let's have some different text!"?


Solution

  • createShadowRoot() is related to Shadow DOM v0 and it won't work with <slot> elements but only with <content> elements.

    <slot> is related to Shadow DOM v1 and it won't work with createShadowRoot() but only with attachShadow().

    Because Shadow DOM v0 is deprecated I recommend to use v1 and therefore to replace createShadowRoot:

     var root = this.attachShadow( { mode: 'open' } )
    

    Note: you should also use Custom Elements v1 instead of v0