Extending paper-fab removes ripple effect - polymer

I have tried to extend paper-fab element but after that I lost ripple effect.
My code looks like this:
<polymer-element name="custom-fab" attributes="name count" extends="paper-fab">
<template>
<style>
:host{
margin: 5px;
};
</style>
<shadow></shadow>
</template>
<script>
Polymer({
count: 0,
created: function() {
this.name = {};
}
})
</script>
</polymer-element>

That was because my element was empty, I get the ripple effect again after adding some text to label attribute.
<custom-fab label="test"></custom-fab>

Related

How can I bind a polymer behavior to a child element?

I am reading about Behaviors in Polymer.
I copy/pasted the example for the highlight-behavior.html:
<script>
HighlightBehavior = {
properties: {
isHighlighted: {
type: Boolean,
value: false,
notify: true,
observer: '_highlightChanged'
}
},
listeners: {
click: '_toggleHighlight'
},
created: function() {
console.log('Highlighting for ', this, 'enabled!');
},
_toggleHighlight: function() {
this.isHighlighted = !this.isHighlighted;
},
_highlightChanged: function(value) {
this.toggleClass('highlighted', value);
}
};
Then, in my element i have the following (just the important parts):
<link rel="import" href="highlight-behavior.html">
<dom-module id="highlighting-test">
<template>
<style>
:host {
display: block;
background-color: red;
}
:host.highlighted {
background-color: green;
}
.highlighted {
background-color: green;
}
</style>
<h1>Click anywhere here to toggle highlighting!</h1>
</template>
<script>
Polymer({
is: 'highlighting-test',
behaviors: [HighlightBehavior]
});
</script>
</dom-module>
Now the problem is that the toggling of the highlighted class works when clicking inside the host element but it is not highlighting just the h1 element. It is adding the highlighted class to the host element.
This is how it is rendered in the browser:
<highlighting-test class="highlighted">
<h1 class="style-scope highlighting-test">Click anywhere here to toggle highlighting!</h1>
</highlighting-test>
When clicking I indeed see that it toggles the highlighted class on the host element highlighting-test and the background changes.
How can I make sure that the highlighting behavior is applied to just the h1 tag?
Use this.toggleClass(className, bool, this.$.id_of_element)
Change:
_highlightChanged: function(value) {
this.toggleClass('highlighted', value);
}
to:
_highlightChanged: function(value) {
this.$.hId.toggleClass('highlighted', value);
}
And in HTML add an ID to H1:
<h1 id="hId">Click anywhere here to toggle highlighting!</h1>

Polymer add class when property is true

I have seen this in angular before and wondered if this is possible in polymer as well. Angular - What is the best way to conditionally apply a class?
I have set up a property named 'animated':
animated: {
type: Boolean,
value: false,
},
When animated is true, a div inside my element should have a css class of .animate.
<div class=""></div>
For now I have done that inside of the ready function.
But since I came across that Stackoverflow question I wondered if this is prossible in polymer.
Thanks!
One way to do that is using a function as follow:
<div class$="{{_getClass(animated)}}"></div>
Where class$ with $ symbol indicates to Polymer's that property is generate using data binding. So, your _getClass function will look like this:
_getClass: function(animated){
return animated ? "animate" : "";
}
When animate property changes, the _getClass function will be invoked and this function will return the string that indicates the class you need.
You can also use toggleClass method of Polymer
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
<dom-module id="my-element">
<template>
<style>
.show {
display: block !important;
border: 1px solid black;
}
.hide {
width: 100px;
height: 100px;
display: none;
}
</style>
<div class="hide" id="toggle"></div>
<button on-tap="_toggleDiv">Press to toggle</button>
</template>
</dom-module>
<script>
Polymer({
is: 'my-element',
properties: {
show: {
type: Boolean,
value: false
}
},
_toggleDiv: function() {
this.show = !this.show;
this.toggleClass('show', this.show, this.$.toggle);
}
});
</script>
<my-element></my-element>

Google Polymer: paper-dialog doesn't work with google-map inside

<paper-button onclick="map.open()">Central Park</paper-button>
<paper-dialog id="map" entry-animation="scale-up-animation" exit-animation="fade-out-animation" with-backdrop>
<div class="dialog-map">
<h>sdoihsdf</h>
<google-map latitude="37.77493" longitude="-122.41942" fit-to-markers></google-map>
</div>
</paper-dialog>
When i include google-map into paper-dialog, second doesn't appear, but when i delete map, all works properly. If write google-map outside of this code, for example after paper-dialog, map and dialog work. Example with map inside dialog on polymer i haven't seen, please help
If you look in the console, you are likely getting a "missing API key" warning. You need to get an API key here:
https://developers.google.com/maps/documentation/javascript/get-api-key
Then provide your API key to your google-map component:
<google-map
api-key="[[yourApiKeyHere]]"
latitude="37.77493"
longitude="-122.41942"
fit-to-markers>
</google-map>
You might need to specify exact height/width for your google-map to make sure it's visible in the dialog:
google-map {
height: 200px;
width: 300px;
}
I was able to get a local demo working:
<dom-module id="map-dialog">
<template>
<style>
:host {
display: block;
}
google-map {
height: 200px;
width: 300px;
}
</style>
<paper-dialog id="dialog">
<google-map
api-key="[[apiKey]]"
latitude="37.77493"
longitude="-122.41942"
fit-to-markers></google-map>
<paper-dialog>
</template>
<script>
Polymer({
is: 'map-dialog',
properties: {
apiKey: {
type: String,
value: function() {
// Return your API key here!!
}
},
},
ready() {
this.$.dialog.open();
}
});
</script>
</dom-module>

Why is my CSS taking effect outside of my template?

I am importing a web component containing a template into index.html. Why is the style in my-template having an effect on the paragraph in index.html.
Put another way, why is all the text in index.html rendered as blue?
I thought CSS inside templates was namespaced in some way. Is this not the case?
index.html
<!DOCTYPE html>
<html>
<head>
<style> p { color: red; }</style>
<link rel="import" href="my-component.html"/>
</head>
<body>
<p>FOO</p>
<my-component></my-component>
</body>
</html>
my-component.html
<template id="my-template">
<style>
p {
color: blue;
}
</style>
<p class="foo">BAR</p>
</template>
<script>
(function() {
var importDoc, myComponentProto;
importDoc = document.currentScript.ownerDocument;
myComponentProto = Object.create(HTMLElement.prototype);
myComponentProto.createdCallback = function() {
var template1, template1Clone;
template1 = importDoc.querySelector('#my-template');
template1Clone = importDoc.importNode(template1.content, true);
this.appendChild(template1Clone); // Insert into the DOM.
};
document.registerElement('my-component', {
prototype: myComponentProto
});
}())
</script>
I think what you want is a scoped stylesheet. Try adding the scoped attribute:
<style scoped>
p {
color: blue;
}
</style>
You should initially create shadow root to hide your template dom into shadow:
myComponentProto.createdCallback = function() {
var shadow = this.createShadowRoot();
shadow.appendChild(importDoc.querySelector('#my-template').content);
};
Live preview: http://plnkr.co/edit/QrvYEUYvzIfstUEoD4Od?p=preview

Polymer - styling childnodes of host

first, i searched for similar questions but haven't found a solution for my problem, which is basically simple, i guess. :)
I built a simple image-slider for clearing up the whole concepts of web components for myself with a real world example.
My custom component is made out of 5 components and a headline.
stage-slider
stage-element
h1
stage-button
stage-teaserdock
stage-teaser
The component slides fine. Now i wanted to add teaser navigation at the bottom. So first i tried adding a single teaser item.
Ok.. what i want to do is access an element inside of the stage-slider:
<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../stage-element/stage-element.html">
<link rel="import" href="../stage-button/stage-button.html">
<polymer-element name="stage-slider" attributes="items slideInterval">
<template>
<style>
:host {
width: 960px;
height: 485px;
position: absolute;
top: 50%;
left: 50%;
margin: -242px 0px 0px -480px;
overflow: hidden;
display: block;
}
:content .teaser
{
left: 30px;
}
</style>
<div id="wrapper">
<template id="slider" repeat="{{item in items}}">
<stage-element headline="{{item.headline}}"
image="{{item.image}}"
buttonLabel="{{item.buttonLabel}}"
buttonTargetWindow="{{item.buttonTargetWindow}}"
buttonTargetURL="{{item.buttonTargetURL}}">
</stage-element>
</template>
<content class="teaser" select="stage-teaser"></content>
</div>
</template>
<script src="./libs/TweenLite/easing/EasePack.min.js"></script>
<script src="./libs/TweenLite/plugins/CSSPlugin.min.js"></script>
<script src="./libs/TweenLite/TweenLite.min.js"></script>
</polymer-element>
<script>
Polymer('stage-slider',
{
slideInterval: 7000,
items: [],
index: 0,
ready: function ()
{
console.log('-----------------');
console.log('stage slider ready!');
},
attached: function ()
{
console.log('-----------------');
console.log('stage slider attached!');
this.$.wrapper.style.width = (960 * (this.items.length)).toString() + "px";
//
if (this.items.length > 1 && this.slideInterval != 0)
{
var that = this;
setInterval(function ()
{
that.startSliding(that);
}, this.slideInterval
);
}
},
startSliding: function (shadowDom)
{
console.log('More children than 1 -> SLIDE EM!');
TweenLite.to(shadowDom.$.wrapper, 1.5, {
marginLeft: -960,
ease: Expo.easeInOut,
onStart: function ()
{
console.log('tween started'); //, this = ', this);
},
onComplete: function ()
{
// console.log('tween complete');
// console.log(shadowDom.$.wrapper.getElementsByTagName('stage-slide')[0]);
shadowDom.$.wrapper.style.marginLeft = 0;
shadowDom.$.wrapper.appendChild(shadowDom.$.wrapper.getElementsByTagName('stage-element')[0]);
}});
}
});
</script>
This is how my markup looks like:
<stage-slider slideInterval="0"
items='[
{
"headline" : "Test headline",
"image" : "img/slide0.jpg",
"buttonLabel" : "Test buttonlabel",
"buttonTargetURL" : "http://www.google.com"
}
]'>
<stage-teaser class="teaser"
image="img/teaser0.jpg"
headline="Test teasertext"
targetURL="http://google.com">
</stage-teaser>
</stage-slider>
So there is a stage-teaser element nested inside my stage-slider element.
I thought i have to distribute it to the content tag inside my template element. Which is why there is a content tag like this:
<content class="teaser" select="stage-teaser"></content>
It displays the teaser item correctly.
But now i want to define its css from within the slider component. This is where i am totally stuck..
I can access the element itself with :host, thats good.
But how do i access the content element, which renders the teaser?
i tried the following:
:host(stage-teaser),
:host(.teaser),
:host(#teaser),
:content .teaser,
:host(:content .teaser),
as you can see.. i am kinda stuck. :-/
any idea would be cool!
thanks,
Rob
I suspect that the issue you're seeing is just a typo. Instead of :content you want ::content. Here's a jsbin showing a simple example: http://jsbin.com/mijifiru/1/edit and for more info on styling web components with the shadow DOM, check out this article: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201/
If that doesn't solve the issue it would be helpful if you reduced your code down to a Minimal, Complete, and Verifiable example, and for bonus points do so in an online editor like jsbin.
<polymer-element name='my-container' noscript>
<template>
<style>
::content .innerContent {
background-color: red;
}
</style>
Shadow Dom
<content></content>
</template>
</polymer-element>
<my-container>
<div class='innerContent'>Contained matching Light DOM</div>
<div>Contained unmatched Light DOM</div>
</my-container>