Search code examples
polymerpolymer-2.x

Polymer 2: How to extend an element with a slot, then stamp children template in that slot?


How would I go about extending an element that has a slot in its template, and stamp my child element’s dom in that slot?

I’m trying to override the child’s template method (like that) but so far I was unsuccessful.

What I’m trying to do is extending a paper-dropdown-menu to always have a certain dropdown content, while keeping all of paper-dropdown-menu input features (validation, etc.) without wiring all by hand with a "wrapper" component.


Solution

  • Found a way! It's just replacing the parent's slot node with the child's node you want to stamp instead, here's an example:

    <dom-module id="custom-child">
      <template>
        <what-you-want-to-stamp slot="parent-slot-name"></what-you-want-to-stamp>
      </template>
    
      <script>
        (() => {
          const CustomParent = customElements.get('custom-parent')
    
          let memoizedTemplate
          class CustomChild extends CustomParent {
            static get is() {
              return 'custom-child'
            }
    
            static get template() {
              if (!memoizedTemplate) {
                memoizedTemplate = Polymer.DomModule.import(this.is, 'template')
                let whatYouWantToStamp = memoizedTemplate.content.querySelector('what-you-want-to-stamp')
    
                let parentTemplateContent = document.importNode(CustomParent.template.content, true)
                let slot = parentTemplateContent.querySelector('slot')
    
                memoizedTemplate.content.insertBefore(parentTemplateContent, whatYouWantToStamp)
                memoizedTemplate.replaceChild(whatYouWantToStamp, slot)
              }
    
              return memoizedTemplate
            }
          }
    
          customElements.define(CustomChild.is, CustomChild)
        })()
      </script>
    </dom-module>