Merc Merc - 5 months ago 96
Javascript Question

Change color iron-icon when tapped

I have a very basic example where I want to change the color of a iron-icon when it's tapped.

I use iron-selector for the tapping:

<template>

<style>

:host {
display: block;
padding: 10px;
--iron-icon-fill-color: blue;
};

.iron-selected iron-icon {
--iron-icon-fill-color: red;
};

.iron-selected iron-icon {
fill: purple;
}

</style>

<iron-meta id=meta key="info" value="some"></iron-meta>

<iron-meta id=meta key="sub">
<a href="some"></a>
</iron-meta>

<iron-selector id="one" selected="0">
<div><iron-icon icon="android" class="ico"></iron-icon></div>
<div><iron-icon icon="menu" class="ico"></iron-icon></div>
</iron-selector>


</template>


I was told before that this is a limitation of the shim, where only one custom value per element-scope can be kept.

Writing a "straight" selector (see the change in "pink") actually works.

Now... if I wanted to use the variables provided by the component (
--iron-icon-fill-color
) rather than manipulating the CSS directly, what would I need to write? (or, is it actually impossible?)

Answer

UPDATE: The newly released Polymer 1.6.0 supports native CSS properties (no shim), so your code would work without updateStyles().

To enable native CSS properties, initialize the Polymer variable before importing polymer.html:

<script>Polymer = {lazyRegister: true, useNativeCSSProperties: true};</script>

HTMLImports.whenReady(_ => {
  "use strict";

  Polymer({
    is: 'x-foo'
  });
});
<head>
  <base href="https://polygit.org/polymer+1.6.0/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>

  <!-- Enable native CSS properties (instead of shim) -->
  <script>Polymer = {lazyRegister: true, useNativeCSSProperties: true};</script>
  <link rel="import" href="polymer/polymer.html">

  <link rel="import" href="iron-selector/iron-selector.html">
  <link rel="import" href="iron-icons/iron-icons.html">
</head>

<body>
  <x-foo></x-foo>

  <dom-module id="x-foo">
    <template>
      <style>
        :host{
         --iron-icon-fill-color: blue;
        }
        .iron-selected {
          background: #eee;
        }
        .iron-selected iron-icon {
          --iron-icon-fill-color: pink;
        }
      </style>

      <iron-selector selected="0">
        <div>
          <iron-icon icon="android" class="ico"></iron-icon>
        </div>
        <div>
          <iron-icon icon="menu" class="ico"></iron-icon>
        </div>
      </iron-selector>
    </template>
  </dom-module>
</body>

codepen


From Polymer 1.5.0 docs (emphasis mine):

Polymer's custom property shim evaluates and applies custom property values once at element creation time.

Since you're updating the style with a custom property dynamically (i.e., after element creation), the custom property would have to be reapplied by calling updateStyles(). You could listen to the <iron-selector>'s iron-select event to trigger this update.

// template
<iron-selector on-iron-select="_updateStyles">

// script
Polymer({
  ...
  _updateStyles: function() {
    this.updateStyles();
  }
});

HTMLImports.whenReady(_ => {
  "use strict";

  Polymer({
    is: 'x-foo',
    _updateStyles: function() {
      this.updateStyles();
    }
  });
});
<head>
  <base href="https://polygit.org/polymer+1.5.0/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="polymer/polymer.html">
  <link rel="import" href="iron-selector/iron-selector.html">
  <link rel="import" href="iron-icons/iron-icons.html">
</head>

<body>
  <x-foo></x-foo>

  <dom-module id="x-foo">
    <template>
      <style>
        :host{
         --iron-icon-fill-color: blue;
        }
        .iron-selected {
          background: #eee;
        }
        .iron-selected iron-icon {
          --iron-icon-fill-color: pink;
        }
      </style>

      <iron-selector selected="0" on-iron-select="_updateStyles">
        <div>
          <iron-icon icon="android" class="ico"></iron-icon>
        </div>
        <div>
          <iron-icon icon="menu" class="ico"></iron-icon>
        </div>
      </iron-selector>
    </template>
  </dom-module>
</body>

codepen

Comments