<link rel="import" href="../../bower_components/iron-icons/maps-icons.html"> <link rel="import" href="../../bower_components/paper-material/paper-material.html"> <link rel="import" href="../catalog-element/catalog-element.html"> <link rel="import" href="../catalog-package/catalog-package.html"> <link rel="import" href="../hero-image/hero-image.html"> <link rel="import" href="../package-symbol/package-symbol.html"> <link rel="import" href="../element-action-menu/element-action-menu.html"> <dom-module id="element-card"> <template> <style> :host { display: block; margin: 10px 10px 10px 0; cursor: pointer; border-radius: 4px; border: 1px solid #d0d0d0; background: white; flex: 1 250px; max-width: calc(33% - 10px); transition-properties: opacity, box-shadow; transition-duration: 0.4s; -webkit-transition-properties: opacity, box-shadow; -webkit-transition-duration: 0.4s; } @media (max-width: 1070px) { :host { max-width: calc(50% - 10px); } } @media (max-width: 530px) { :host { max-width: calc(100% - 10px); } } :host(:hover), :host(.hover) { @apply(--shadow-elevation-2dp); } h3 { font-size: 16px; font-weight: 500; margin: 0; padding: 10px 16px 0; } p { margin: 0; } #el { cursor: pointer; } #hero { width: 100%; height: 120px; background: #ccc; border-radius: 3px 3px 0 0; overflow: hidden; border-bottom: 1px solid #e5e5e5; } #hero > img { width: 100%; height: 100%; } .meta { border-top: 1px solid; border-bottom: 1px solid; border-color: var(--divider-color); padding: 10px 16px; } .meta + .meta { border-top: 0; } .meta:last-child { border-bottom: 0; } #el-desc { @apply(--paper-font-body1); color: var(--secondary-text-color); margin: 0; padding: 10px 16px; height: 75px; } .package { font-size: 12px; font-weight: 500; } .package package-symbol { margin: 0 15px 0 0; } .package > a:hover { text-decoration: underline; } .tags iron-icon { margin: 0 15px 0 0; padding: 5px; color: var(--secondary-text-color); --iron-icon-size: 18px; } .tag { margin-right: 4px; font-size: 12px; } .tag:hover { text-decoration: underline; } .tag:after { margin-left: -3px; content: " ,"; } .tag:last-of-type:after { content: ""; } </style> <a href="[[_getElementLink(item.name)]]"> <div id="content" class="vertical layout"> <div id="el" view="docs"> <div id="hero" on-mouseenter="_mouseEnter" on-mouseleave="_mouseLeave" style$="[[_computeStyle(color)]]"> <img src="[[_getImageSrc(item.hero)]]"> </div> <h3>[[item.name]]</h3> </div> <p id="el-desc">[[item.description]]</p> <div class="horizontal layout center meta package"> <package-symbol symbol="[[packageSymbol]]" color="[[color]]"></package-symbol> <a href="[[_getPackageLink(item.package)]]">[[item.package]]</a> </div> <div class="meta tags"> <iron-icon icon="maps:local-offer" class="flex-none"></iron-icon> <template is="dom-repeat" items="[[item.tags]]" as="tag"> <a href="[[_getTagLink(item.package, tag)]]" class="tag">[[tag]]</a> </template> </div> </div> </a> </template> </dom-module> <script> (function() { var sharedActionMenu = null; var activeCard = null; function mouseEnter() { if (activeCard) { activeCard.showActions(); } } function mouseLeave() { if (activeCard) { activeCard.hideActions(); } } Polymer({ is: 'element-card', enableCustomStyleProperties: true, properties: { item: Object, color: String, packageSymbol: String }, observers: [ '_updatePackage(_element)' ], attached: function() { this.style.opacity = 0; this.async(function() { this.style.opacity = 1; }, 1); }, detached: function() { if (activeCard === this) { activeCard = null; if (sharedActionMenu) { Polymer.dom(this.parentNode).removeChild(sharedActionMenu); sharedActionMenu = null; } } }, _tagClicked: function(e) { e.stopPropagation(); this.fire('update-params', {tag: e.currentTarget.name}); }, _computeStyle: function(color) { return 'background-color:' + color; }, _getElementLink: function(elementName) { return '/elements/' + elementName; }, _getImageSrc: function(src) { return src && src.length ? src : '/images/hero/random-' + Math.ceil(Math.random() * 4) + '.svg'; }, _getPackageLink: function(packageName) { return '/browse?package=' + packageName + '&view=cards'; }, _getTagLink: function(packageName, tag) { return '/browse?tag=' + tag + '&view=cards'; }, showActions: function() { var top = this.$.hero.offsetTop; var left = this.$.hero.offsetLeft; var width = this.$.hero.offsetWidth; if (!sharedActionMenu) { sharedActionMenu = document.createElement('element-action-menu'); sharedActionMenu.classList.add('cards'); sharedActionMenu.classList.add('hidden'); sharedActionMenu.addEventListener('mouseenter', mouseEnter); sharedActionMenu.addEventListener('mouseleave', mouseLeave); } if (!sharedActionMenu.parentNode) { Polymer.dom(this.parentNode).appendChild(sharedActionMenu); } top += this.$.hero.offsetHeight - sharedActionMenu.offsetHeight; sharedActionMenu.element = this.item.name; sharedActionMenu.style.top = top + 'px'; sharedActionMenu.style.left = left + 'px'; sharedActionMenu.style.width = width + 'px'; this._layoutIfNeeded(sharedActionMenu); sharedActionMenu.classList.remove('hidden'); this.classList.add('hover'); sharedActionMenu.cancelDebouncer('hide'); }, hideActions: function() { if (sharedActionMenu && sharedActionMenu.element == this.item.name) { sharedActionMenu.debounce('hide', function() { sharedActionMenu.classList.add('hidden'); }, 10); this.classList.remove('hover'); } }, _mouseEnter: function() { activeCard = this; mouseEnter(); }, _mouseLeave: function(e) { mouseLeave(); }, _layoutIfNeeded: function(el) { return el.offsetTop; } }); })(); </script>