roydukkey
roydukkey

Reputation: 3288

Isolate polymer custom elements for use in others custom elements

Is it possible to ensure certain custom elements are available only within particular custom element?

For example, I've created a site-heading and a help-icon element.

<polymer-element name="site-heading">
    <template>
        <h1>
            <content></content>
            <content select="help-icon"></content>
        </h1>
    </template>
<polymer-element>

<polymer-element name="help-icon">
    <template>
        <span class="help">
            <img src="/image/help.png" />
            <content></content>
        </span>
    </template>
<polymer-element>

Now this isn't the most practical example, however, let's say the help-icon is a highly specialized element that only has meaning in context to site-heading. How can I force the element to be used only inside of site-heading?

Yay!

<site-heading>
    Super Cool Site Header
    <help-icon>Help Me!</help-icon>
</site-heading>

Nay!

<help-icon>Help Me!</help-icon>

Update 2: @ebidel

It seems this relationship isn't really supported and may not even be in the specs. Here is a real world cases I believe should weight heavy in consideration of scoped (isolated?) elements.

Let's assume a vendor would create a shippable web component. For example, SoundCloud would create a <soundcloud-player> element. A player needs a track list, so they create a <track-info attributes="track-id crop etc">{{HTML for description pane}}</track-info> element.

The <track-info> element is only useful as a child of <soundcloud-player>:

Should we move this conversation somewhere else as it appears we already have the answer to my original question?

Upvotes: 0

Views: 312

Answers (1)

ebidel
ebidel

Reputation: 24119

The HTML parser only reserves a few tags to behave like this (they're ignored if they're not under a certain parent):

  • <option>/<optgroup> can only be used as a child of <select>.
  • <tr> can only be child of <table>
  • others

My first question is whether it help-icon needs to be a component. Composition is a good thing :) If it's useful to you now, it may be useful in other places.

To get this working...I would do what you have done in site-header. Only select <help-icon> using <content select="help-icon"></content>. Second, you can test for what parent the element is a child of in domReady():

<polymer-element name="help-icon" hidden>
  <template>
    <content></content>
  </template>
  <script>
    Polymer('help-icon', {
      domReady: function() {
        // help-icon should only be a parent of site-banner.
        // Unhide
        if (this.parentNode.localName == 'site-banner') {
          this.hidden = false;
        } else {
          //this.remove(); // optionally remove it from the dom.
        }
      }
    });
  </script>
</polymer-element>

Demo: http://jsbin.com/dazewiqa/1/edit

Upvotes: 1

Related Questions