Search code examples
javascriptpolymer-2.xcustom-element

Polymer 2.0 How to extend PolymerElements app-layout and app-drawer


I am very new to Polymer 2.0 and I am trying out creating custom elements.

I am able to extend my own custom element and it works fine. I am just trying to find out if I can extend PolymerElements app-layout's app-drawer element found here https://www.webcomponents.org/element/PolymerElements/app-layout

I tried this but it is not working.

<link rel="import" href="/bower_components/app-layout/app-layout.html">

class MyElement extends AppLayout {
  static get is() { return 'my-element'; }
};

customElements.define(MyElement.is, MyElement);

It gives me an error saying Uncaught ReferenceError: AppLayout is not defined. Even if I tried to make sure that app-layout has correct import script and I can use the app-layout elements like app-drawer.

Is it the name AppLayout that is wrong? I have tried different names like Polymer.Applayout etc. but still same error. I have tried extending my own custom element which resides in the same bower_components folder and it works without error.

class ExtendedElement extends MyElement {
  static get is() { return 'extended-element'; }
};

Any suggestions? Thanks!


Solution

  • I manage to find something that works here and here

    This sample will extend <app-drawer> element of <app-layout>

    <dom-module id="my-sub-element">
      <template id="styles">
        <style>
          div {
            background-color: gray;
          }
        </style>
      </template>
    
      <script>
    
      (function() {
        let subTemplate;
    
        class MySubElement extends customElements.get('app-drawer') {
          /**
           * This will return our template inherited from superclass <app-drawer> with our styles inserted
           */
          static get template() {
            if (!subTemplate) {
              // first clone our superclass <app-drawer> template
              let superClass = customElements.get('app-drawer');
              subTemplate = superClass.template.cloneNode(true);
    
              // here we will get the content of our <style> so we can insert them into the superclass <style>
              // note the added id="styles" in our template tag above
              const subStyle = Polymer.DomModule.import('my-sub-element', 'template#styles').content;
    
              // get the content of current style from superClass
            const superStyle = subTemplate.content.querySelector('style');
    
              // append our added style at the bottom of the current style to get higher priority
              superStyle.parentNode.appendChild(subStyle);
            }
            return subTemplate;
          }
    
        }
    
        customElements.define('my-sub-element', MySubElement);
    
      })();
    
      </script>
    </dom-module>
    

    I hope this helps. This is working for me at the moment. I read through this discussion here to have clearer idea on what is going on when extending . Please add/edit my answer if there is a better way to do this. Cheers!