Polymer: [1.1.0] Support for extending custom elements?

Created on 15 Aug 2015  Â·  28Comments  Â·  Source: Polymer/polymer

Any update on when this Polymer 0.5 feature will be re-implemented in Polymer 1.x? Back when Polymer 0.8 was released it was mentioned that the intent was to re-introduce this in Polymer 1.1 ...

1.x enhancement p2

Most helpful comment

(My secret hope is to see Polymer with inheritance that allows <paper-input>'s codebase to be simplified, as I feel that composition in that case is pushed a little too much, and it makes paper-input duplicating a lot of code which is a shame...

All 28 comments

This feature didn't make it into 1.1 but it is still planned to be added soon. Stay tuned...

Is there a roadmap somewhere where I can track the version in which this feature will land?

For those interested, I'm achieving something like this by creating a way to convert a component into its behavior equivalent, then using that behavior as needed. It's in a project called misbehave. Looks something like this,

<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../misbehave/misbehave.html">
<link rel="import" href="base-component.html">

<script>
  Polymer({

    is: 'ext-component',

    // ext-component now effectively extends the Polymer component base-component
    behaviors: [
      document.createElement('base-component').toBehavior()
    ]

  });
</script>

@devinivy, from source code it looks like you do not do anything with CSS/Shadow DOM. We are already heavily using regular behaviors, but actual extending is much more than just that.

@nazar-pc of course! This does not deal with CSS and shadow DOM, though there is a feature in the works that will create injection points for the shadow DOM of the mixed-in elements.

What this library does allow you to do is extend functionality of third-party components. For example, I might want to create an element that has a superset of the iron-ajax interface, but I don't want to duplicate the iron-ajax interface and use composition. This would allow you to do that.

Behaviors are not quite fit for component extension (in the sense of inheritance) anyway because they're mixins.

This issue seems really crucial to me. I want to encourage you to treat it with highest priority. Polymer 1.0 has lost some ease of development over 0.5. The lack of element inheritance very often gives rise to dirty implementations by workarounds (encapsulation).

With element inheritance by encapsulation, you suffer from

  • unnecessary number of dummy elements, giving rise to an overloaded DOM tree
  • impossibility to apply standard CSS properties - you cannot restyle the border of an extended button in an abstract fashion
  • long-winded, inefficient attribute hand-overs like
    <input is="iron-input" id="input"
        aria-labelledby$="[[_ariaLabelledBy]]"
        aria-describedby$="[[_ariaDescribedBy]]"
        disabled$="[[disabled]]"

( https://github.com/PolymerElements/paper-input/blob/master/paper-input.html#L92 )

Actually, in my eyes, the basics for simple way of element extension have been laid by the Web Components and ECMAScript standards - I don't see the complexity of the issue.

Extend the element prototype by ES object extension. Override the parent template shadow root adding the child's template as second shadow root to the element. The developer has the possibility to reference overridden shadow roots by the (standardized) <shadow> element, or not to override the template at all.

Did I miss something?

I thought multiple shadow roots were scrapped for Shadow DOM v1 based on browser vendor consensus.

@daluge, there is at least one small big thing called Shady DOM:)
I've fixed some bugs in Polymer myself and sometimes simple things become quite complex to fix/implement.

@miztroh I was not aware of this, so in fact I missed something, sorry

As I remember it was about creating multiple Shadow Roots on single element, however I don't know how it relates to inheritance.

I think Polymer 0.5 supported inheritance by creating multiple shadow roots
in the inheriting element: one for the original element's local DOM and
another for the inheriting element's local DOM. Since multiple shadow
roots aren't a thing anymore, I'm sure this complicates implementing
inheritance.
On Oct 17, 2015 10:15 AM, "Nazar Mokrynskyi" [email protected]
wrote:

As I remember it was about creating multiple Shadow Roots on single
element, however I don't know how it relates to inheritance.

—
Reply to this email directly or view it on GitHub
https://github.com/Polymer/polymer/issues/2280#issuecomment-148922515.

In most cases, overriding the template is not a requirement but the ability
to extend the API and retain the template model perfectly suffices.

I decided to employ Polymer on a large project. As we won't rely on pure
Paper/Material until the end of the days, abstracting UI widgets is a basic
requirement () and also adding missing functionality. At
the moment, we can only do this encapsulating items.

The moment we do this, we completely loose the ability to apply style rules
such as border-radius, background-color on the abstracted shells
(). Furthermore, we obtain code compounds like
https://github.com/PolymerElements/paper-input/blob/master/paper-input.html#L92
which we don't want.

At the moment, I see no way to abstract custom elements maintaining their
integrity with CSS. As long this is not given, I see no other way than
migrating back to Polymer 0.5. The project is really awesome and it takes
the web to a new level. But I'm not sure Polymer 1.1 is really yet
'production ready' already.

On 17 October 2015 at 17:45, Jonathan Cox [email protected] wrote:

I think Polymer 0.5 supported inheritance by creating multiple shadow roots
in the inheriting element: one for the original element's local DOM and
another for the inheriting element's local DOM. Since multiple shadow
roots aren't a thing anymore, I'm sure this complicates implementing
inheritance.
On Oct 17, 2015 10:15 AM, "Nazar Mokrynskyi" [email protected]
wrote:

As I remember it was about creating multiple Shadow Roots on single
element, however I don't know how it relates to inheritance.

—
Reply to this email directly or view it on GitHub
https://github.com/Polymer/polymer/issues/2280#issuecomment-148922515.

—
Reply to this email directly or view it on GitHub
https://github.com/Polymer/polymer/issues/2280#issuecomment-148925758.

We're stuck using Polymer 0.5 as well until Polymer 1.x adds support for extending custom elements. Two months ago sorvell said "it is still planned to be added soon. Stay tuned..." Any idea on how much longer this is expected to take?

This would also help the :santa: port.

The extends and extends-plus-set-object-array branches are stuck at March... any news on this one?

@tjsavage

(My secret hope is to see Polymer with inheritance that allows <paper-input>'s codebase to be simplified, as I feel that composition in that case is pushed a little too much, and it makes paper-input duplicating a lot of code which is a shame...

Probably trying my luck posting here, but I finally got to the part of my project where inheritance would be handy... or, would it? Am I missing a simple technique that makes it (yet again) inheritance an overkill?

http://stackoverflow.com/questions/38840911/extending-polymers-iron-ajax-without-inheritance

As far as I know, there is no better way than copy pasting all properties
and redefining them on the element. I do have another proposal in #3847
with another solution, since inheritance does not appear to land any time
soon.

On Tue, 9 Aug 2016, 04:00 Tony Mobily, [email protected] wrote:

Probably trying my luck posting here, but I finally got to the part of my
project where inheritance would be handy... or, would it? Am I missing a
simple technique that makes it (yet again) inheritance an overkill?

http://stackoverflow.com/questions/38840911/extending-polymers-iron-ajax-without-inheritance

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/Polymer/polymer/issues/2280#issuecomment-238432265,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AFrDb6fehcn4MeuOqtdYQDAT58Ellrbdks5qd98ggaJpZM4FsFtz
.

I have been evaluating some libraries to start a new project and this almost made go for another framework, BUT it is working in 2.0-preview!! :)

<dom-module id="my-datepicker">

  <script>
(function() {
  'use strict';

  class MyDatePicker extends customElements.get('vaadin-date-picker') {
    static get is() { return 'my-datepicker' }

    constructor() {
        super();
        this.i18n = {...}
    }


}

customElements.define(MyDatePicker.is, MyDatePicker);

})();
</script>
</dom-module>

Hey @erichmx! I am trying to extend paper-button like so:

class MyButton extends customElements.get('paper-button') {
   ...
}

Sadly, this doesn't seem to work for me. Can you provide a demo of what you've done? Thanks!

Hi @phasjim, are you using the 2.0-preview branch? The only thing I didn't include in the previous code sample was the html import for the parent element, paper-button in your case.

Can you post your complete element?

@erichmx Yes, I'm using the 2.0-preview branch in both Polymer and PolymerElements/paper-button. At the top I've included my imports:

<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../polymer/polymer-element.html">
<link rel="import" href="../paper-button/paper-button.html">

I was able to extend Polymer.Element fine with

class MyButton extends Polymer.Element  { ... }

But when I try your method, I get a console error Uncaught DOMException: Failed to construct 'CustomElement': The result must not have attributes. I'm working to get a demo for you right now. Are you extending a Polymer 1.x element? Thanks!

I have only extended Polymer 2.0-preview elements. I have seen the error you send when I've tried to use or extend an 1.x element in 2.0. But paper-button has its 2.0-preview branch, if you use the element's 2.0-preview branch (not just Polymer, but also the element) and extend it, it should work.

While setting up a codepen for you, I somehow got it to work 😄 You can view a demo at http://codepen.io/phasjim/pen/oZgYWB. (It breaks on the ripple, but at least the extends work.) I must have messed up a bower install on my machine... Thanks so much for all your help @erichmx!

@phasjim Your codepen helped me understand how the subclass can 'extend' the template as well! I had to include my properties in the subclass's template, but it works. For my case my base class is a custom 'table-element' that has two properties - 'columns' and 'rows'. When I subclass this base class I have to include a template element in which I can add styles. In order to do this I found I needed to include the 'columns' and 'rows' in the subclass template as follows:

<dom-module id="collection-table"> <template> <table-element columns="[[columns]]" rows="[[rows]]"></table-element> </template>

This allows the subclass of the custom element to load and display the base class data.

Now I just need to figure out how to get my styles injected into the base class properly :-)

@phasjim @erichmx @gechols see if this helps:
https://github.com/Polymer/polymer/issues/2510#issuecomment-289123187

Here's how you can extend other elements: https://www.polymer-project.org/2.0/docs/devguide/custom-elements#extending-elements.

In addition, if you want to modify the template of the element you are extending, follow this guide: https://www.polymer-project.org/2.0/docs/devguide/dom-template#inherited-templates

Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yairopro picture yairopro  Â·  3Comments

dandv picture dandv  Â·  4Comments

SergRZ picture SergRZ  Â·  3Comments

masaoliou picture masaoliou  Â·  3Comments

limonte picture limonte  Â·  3Comments