Skip to content

Instantly share code, notes, and snippets.

@dnegstad
Last active January 2, 2019 17:50
Show Gist options
  • Save dnegstad/eee660aa32efd906082c to your computer and use it in GitHub Desktop.
Save dnegstad/eee660aa32efd906082c to your computer and use it in GitHub Desktop.
Polymer WebComponents in ember-cli >= 0.0.41
// Add these dependencies
"dependencies": {
"polymer": "Polymer/polymer#~0.5.1",
"core-elements": "Polymer/core-elements#~0.5.1",
"paper-elements": "Polymer/paper-elements#~0.5.1"
}
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
var pickFiles = require('broccoli-static-compiler');
var mergeTrees = require('broccoli-merge-trees');
var vulcanize = require('broccoli-vulcanize');
var app = new EmberApp();
var polymerVulcanize = vulcanize('app', {
input: 'elements.html',
output: 'assets/vulcanized.html',
csp: true,
inline: true,
strip: false,
excludes: {
imports: ["(^data:)|(^http[s]?:)|(^\/)"],
scripts: ["(^data:)|(^http[s]?:)|(^\/)"],
styles: ["(^data:)|(^http[s]?:)|(^\/)"]
}
});
var polymer = pickFiles('bower_components/', {
srcDir: '',
files: [
'webcomponentsjs/webcomponents.js',
'polymer/polymer.js',
'polymer/polymer.html'
],
destDir: '/assets'
});
module.exports = mergeTrees([
polymerVulcanize,
polymer,
app.toTree()
]);
<!--
This file belongs at app/elements.html. Loads the polymer elements as a single file, rather than a bunch of individual link requests.
You can customize the elements loaded here if you don't need certain things or want to add your own custom elements.
-->
<link rel="import" href="../bower_components/core-elements/core-elements.html">
<link rel="import" href="../bower_components/paper-elements/paper-elements.html">
<link rel="import" href="../bower_components/paper-dialog/paper-action-dialog.html">
<link rel="import" href="../bower_components/paper-dialog/paper-dialog-transition.html">
<link rel="import" href="../bower_components/font-roboto/roboto.html">
<link rel="import" href="../bower_components/core-icons/av-icons.html">
<link rel="import" href="../bower_components/core-icons/communication-icons.html">
<link rel="import" href="../bower_components/core-icons/device-icons.html">
<link rel="import" href="../bower_components/core-icons/editor-icons.html">
<link rel="import" href="../bower_components/core-icons/hardware-icons.html">
<link rel="import" href="../bower_components/core-icons/maps-icons.html">
<link rel="import" href="../bower_components/core-icons/notification-icons.html">
<link rel="import" href="../bower_components/core-icons/social-icons.html">
<link rel="import" href="../bower_components/core-animated-pages/transitions/cascade-transition.html">
<link rel="import" href="../bower_components/core-animated-pages/transitions/core-transition-pages.html">
<link rel="import" href="../bower_components/core-animated-pages/transitions/cross-fade.html">
<link rel="import" href="../bower_components/core-animated-pages/transitions/hero-transition.html">
<link rel="import" href="../bower_components/core-animated-pages/transitions/list-cascade.html">
<link rel="import" href="../bower_components/core-animated-pages/transitions/scale-up.html">
<link rel="import" href="../bower_components/core-animated-pages/transitions/slide-down.html">
<link rel="import" href="../bower_components/core-animated-pages/transitions/slide-from-bottom.html">
<link rel="import" href="../bower_components/core-animated-pages/transitions/slide-from-right.html">
<link rel="import" href="../bower_components/core-animated-pages/transitions/slide-up.html">
<link rel="import" href="../bower_components/core-animated-pages/transitions/tile-cascade.html">
<!--
These go right below {{content-for 'head'}} in your app/index.html file
Polymer really doesn't like having other scripts loaded first (especially jQuery).
-->
<script src="assets/webcomponentsjs/webcomponents.js"></script>
<link rel="import" href="assets/vulcanized.html">
// Add these dev dependencies
"devDependencies": {
"broccoli-static-compiler": "^0.1.4",
"broccoli-merge-trees": "^0.2.0",
"broccoli-vulcanize": "^1.0.4"
}
@jlesquembre
Copy link

Cool article! I can now show Polymer components in my ember app, but I don't get how to bind attributes. In my case, I want to react to changes in a text input (paper-input in polymer) Do you know if that is possible?

@JHKennedy4
Copy link

As of Polymer 0.5 (https://blog.polymer-project.org/announcements/2014/10/16/platform-becomes-webcomponents/), platform/platform.js is now webcomponentsjs/webcomponents.js in both Brocfile.json and index.html.

You can see the changes in my fork https://gist.github.com/JHKennedy4/66a8468b7c5f79614396

If there's a way to submit a PR to a gist, let me know. I don't know how to do it.

@dnegstad
Copy link
Author

dnegstad commented Dec 9, 2014

@jlesquembre Direct attribute binding isn't quite there yet. With HTMLBars it works a little better, but you still need to rely on events to watch for property changes. I've been wrapping some components up in Ember components with a few observers and event handlers for more complex cases like dialog boxes.

@dnegstad
Copy link
Author

dnegstad commented Dec 9, 2014

@JHKennedy4 Just ended up upgrading to 0.5 a few days ago. Let me see about pulling in your changes so people aren't getting deprecation warnings.

@dnegstad
Copy link
Author

dnegstad commented Dec 9, 2014

Now updated for the new and improved Polymer 0.5. You'll want to update your broccoli-vulcanize to 1.0.4 or greater to get the latest vulcanize version.

@richieb
Copy link

richieb commented Dec 16, 2014

@dnegstad Could you post a gist or snippet of a working example of Polymer/Ember Components with bindings? That would certainly help. No need to refactor code or post a complete example, just drop a few lines (straight out of your project) in a reply so we can see what you have done.

@Samsinite
Copy link

@richieb, you can listen for fired events from a polymer component by adding an event listener to the element of the component.

polymer custom post-card component:

<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/core-icon-button/core-icon-button.html">

<polymer-element name="post-card">
  <template>
    <style>
    :host {
      display: block;
      position: relative;
      background-color: white;
      padding: 20px;
      width: 100%;
      font-size: 1.2rem;
      font-weight: 300;
        margin-bottom: 30px;
    }
    .card-header {
      margin-bottom: 10px;
    }
    polyfill-next-selector { content: '.card-header h2'; }
    .card-header ::content h2 {
      margin: 0;
      font-size: 1.8rem;
      font-weight: 300;
    }
    polyfill-next-selector { content: '.card-header img'; }
    .card-header ::content img {
      width: 70px;
      border-radius: 50%;
      margin: 10px;
    }
    core-icon-button {
      position: absolute;
      top: 3px;
      right: 3px;
      color: #636363;
    }
    :host([favorite]) core-icon-button {
      color: #da4336;
    }
    </style>
    <div class="card-header" layout horizontal center>
      <content select="img"></content>
      <content select="h2"></content>
    </div>
    <core-icon-button id="favicon" icon="favorite" on-tap="{{favoriteTapped}}"></core-icon-button>
    <content></content>
  </template>
  <script>
    Polymer({
      favoriteTapped: function(event, detail, sender) {
        this.fire('favorite-tapped');
      }
    });
  </script>
</polymer-element>

post-card ember component (js):

import Ember from 'ember';

export default Ember.Component.extend({
  tagName: 'post-card',
  post: null,

  favoriteSelected: function() {
    console.log("Post card favorited");
  },

  didInsertElement: function() {
    var element   = this.$()[0],
        avatarUrl = this.get('post.avatar'),
        self      = this;

    if (element && avatarUrl) {
      var avatarImage = element.getElementsByTagName('img')[0];

      avatarImage.setAttribute('src', avatarUrl);
      element.addEventListener('favorite-tapped', function() {
        self.favoriteSelected();
      });
    }
  }
});

post-card ember component template (handlebars):

<img width="70" height="70">
<h2>{{post.username}}</h2>
<p>{{post.text}}</p>

I'll share my ember-polymer version of the polymer starter tutorial soon.

@Samsinite
Copy link

Hope it helps. While it isn't too hard to do, figuring out how to listen to polymer events from ember took me about 3 hours to research.

@Samsinite
Copy link

I've created the ember-cli addon ember-polymer to automate this task. Thanks @dnegstad for doing the hard part :D. @richieb I put together an example of the polymer starter tutorial where use the technique mentioned above for the post-card ember component which wraps the polymer post-card component.

@richieb
Copy link

richieb commented Dec 30, 2014

Thanks a lot, @Samsinite. Your examples are very helpful. I will give them a go when I resume working on the project. I had put my Ember/Polymer project to rest for a bit.

@dnegstad
Copy link
Author

dnegstad commented Jan 4, 2015

Awesome work on setting up an addon @Samsinite! I've been too busy lately to do anything beyond throwing the examples up here.

@dnegstad
Copy link
Author

dnegstad commented Jan 4, 2015

Also, this other gist may come in handy if anyone starts seeing weird errors in browsers other than chrome when mixing Polymer and Ember.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment