Polymer: Using selectors - polymer

I am using Polymer to create a web component. I want to select the div gutter when the ::host element gets the class full
<link rel="import" href="/polymer/polymer.html">
<dom-module id="smooth-header">
<style>
.full ::content gutter {
color: red;
}
</style>
<template>
<content>
<div class="gutter"></div>
</content>
</template>
<script>....</script>
</dom-module>
But I am not able to select the gutter element with the above selector.
Why should the above selector fail?
Help with an alternative to select it correctly.

You should use :host(selector) to select a class on the host element:
:host(.fill) .gutter {
color: red;
}
<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">
</head>
<body>
<x-foo></x-foo>
<x-foo class="full"></x-foo>
<dom-module id="x-foo">
<style>
:host(.full) .gutter {
color: red;
}
</style>
<template>
<content>
<div class="gutter">
<span>{{foo}}</span>
</div>
</content>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-foo',
properties : {
foo: {
type: String,
value: "Hello world!"
}
}
});
});
</script>
</dom-module>
</body>
codepen

Related

iron-list selected-item observer returns null before sending selected object

I am trying to implement single selection on iron list. For every valid click, I get a null immediately followed by actual value.
Here is the iron-list code
<iron-list items="[[imagearray]]" as="item" id="itemlist" scroll-target="document" selected-item="{{selectedItem}}" selection-enabled grid>
<template>
<div class = "flexchild"style="width:50%">
<iron-image class = "imagecontainer" sizing = "cover" style = "width:calc(100% - 4px); height:180px;"
src=[[item.linkwebp]]></iron-image>
</div>
</template>
</iron-list>
Here is my property object
selectedItem:
{
type:Object,
observer: '_itemSelected'
}
_itemSelected()
{
console.log(this.selectedItem);
*
}
Each time i select an iron-list element, I get null followed by actual element. Any idea whY
Seams there is no error in your code. May cause something else. Below demo link works quite good.
DEMO
<html>
<head>
<base href="https://polygit.org/polymer+:master/components/">
<link rel="import" href="polymer/polymer.html" >
<link rel="import" href="iron-ajax/iron-ajax.html">
<link rel="import" href="iron-list/iron-list.html">
<link rel="import" href="iron-image/iron-image.html">
<script src="webcomponentsjs/webcomponents-lite.js"></script>
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<template>
<style>
:host {
display: block;
height: 100%;
}
</style>
<!--In order to retrive some object data -->
<iron-ajax
auto
id="ajax"
url="https://randomuser.me/api?results=10"
last-response="{{response}}"> </iron-ajax>
<iron-list items="[[response.results]]" as="item" id="itemlist" scroll-target="document" selected-item="{{selectedItem}}" selection-enabled grid>
<template>
<div class = "flexchild" style="width:50%">
<iron-image style ="width: 40px;height:40px; border-radius:30px;" src='[[item.picture.large]]'></iron-image>
<span>[[item.name.first]] [[item.name.last]]</span>
</div><br/>
</template>
</iron-list>
<pre>[[obj]]</pre>
</template>
<script>
HTMLImports.whenReady(function() {
class XFoo extends Polymer.Element {
static get is() { return 'x-foo'; }
static get properties() { return {
selectedItem: {
type:Object,
observer: '_itemSelected'
}
}}
_itemSelected() {
this.obj = JSON.stringify(this.selectedItem, null, 4);
console.log(this.selectedItem);
}
}
customElements.define(XFoo.is, XFoo);
});
</script>
</dom-module>
</body>
</html>

Propagating CSS variables in composited elements

I've got an element (the host) that includes another element (the child).
How can I propagate the value of a CSS variable from the host to the child when the CSS variable is set on the host?
Example:
<!-- Host Element, includes <child-element> -->
<dom-module id="host-element">
<template>
<style>
child-element {
--button-color: var(--menu-button-color);
}
</style>
<child-element><child-element>
</template>
</dom-module>
<!-- Child Element, is declared within <host-element> -->
<dom-module id="child-element">
<template>
<style>
button {
color: var(--button-color);
}
</style>
<button> I should be a red button </button>
</template>
</dom-module>
And ideally I'd be able to use it like so:
<style>
host-element {
--menu-button-color: red;
}
</style>
<host-element><host-element>
Seems to be working(chrome), run the code snippet below
<!doctype html>
<head>
<base href="https://polygit.org/polymer+1.7.1/components/">
<script src="webcomponentsjs/webcomponents-lite.js"></script>
<script>
// Setup Polymer options
window.Polymer = {
dom: 'shadow'
};
</script>
<link rel="import" href="polymer/polymer.html">
</head>
<style is="custom-style">
host-elem {
--menu-button-color: red;
}
</style>
<body>
<host-elem></host-elem>
<!-- Host Element, includes <child-element> -->
<dom-module id="host-elem">
<template>
<style>
child-elem {
--button-color: var(--menu-button-color);
}
</style>
<child-elem><child-elem>
</template>
<script>
Polymer({ is: 'host-elem'});
</script>
</dom-module>
<!-- Child Element, is declared within <host-element> -->
<dom-module id="child-elem">
<template>
<style>
button {
color: var(--button-color);
}
</style>
<button>I should be a red button </button>
</template>
<script>
Polymer({ is: 'child-elem'});
</script>
</dom-module>
</body>

Polymer 1.x: neon-animated-pages not working inside paper-tabs and paper-dialog

Text falls outside dialog
Here is the plunk
I want to implement neon-animated-pages controlled by paper-tabs inside a paper-dialog.
I expect to see the content of tab-a and tab-b contained inside the paper-dialog but instead the content spills over to outside the paper-dialog.
What am I missing?
http://plnkr.co/edit/bPUclBOpghNFVmKMbOzc?p=preview
<link href="tab-a.html" rel="import">
<link href="tab-b.html" rel="import">
<base href="https://polygit.org/polymer+:master/iron-data-table+Saulis+:master/components/">
<link rel="import" href="polymer/polymer.html">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="paper-dialog/paper-dialog.html">
<link rel="import" href="paper-tabs/paper-tabs.html">
<link rel="import" href="iron-pages/iron-pages.html">
<link rel="import" href="neon-animation/neon-animation.html">
<link rel="import" href="neon-animated-pages/neon-animated-pages.html">
<dom-module id="content-el">
<template>
<style></style>
<button on-tap="open">Open Dialog</button>
<paper-dialog id="dialog" modal>
<h2>Dialog Title</h2>
<paper-tabs selected="{{selected}}">
<paper-tab>Tab 1</paper-tab>
<paper-tab>Tab 2</paper-tab>
</paper-tabs>
<neon-animated-pages selected="{{selected}}">
<tab-a entry-animation="slide-from-left-animation"
exit-animation="slide-left-animation"
></tab-a>
<tab-b entry-animation="slide-from-right-animation"
exit-animation="slide-right-animation"
></tab-b>
</neon-animated-pages>
</paper-dialog>
</template>
<script>
(function() {
'use strict';
Polymer({
is: 'content-el',
behaviors: [
Polymer.NeonAnimationRunnerBehavior,
Polymer.NeonAnimatableBehavior,
Polymer.IronResizableBehavior,
],
properties: {
selected: {
type: Number,
value: 0
}
},
open: function() {
this.$.dialog.open();
},
});
})();
</script>
</dom-module>
The off-dialog content is inside <neon-animated-pages>, and inspecting the <neon-animated-pages> reveals that it has no height:
To fix this, apply CSS styles to the <paper-dialog> and the <neon-animated-pages> to set their width/height; and set overflow on the pages to allow scrolling. For example:
<dom-module id="content-el">
<template>
<style>
paper-dialog {
width: 75%;
min-width: 50vw;
}
neon-animated-pages {
margin: 2em;
height: 100%;
min-height: 25vh;
overflow: auto;
}
</style>
...
</template>
</dom-module>
plunker

Polymer 1.x: Imperatively accessing DOM nodes inside a dom-if template

Here is my jsBin.
I want to access by its id a DOM node inside a dom-if template. With my existing code, I expect to see true when attempting to cast these nodes to Booleans, but instead I get false (i.e., undefined).
Steps to recreate the problem:
Open this jsBin.
Understand that the HTML pane on the right is working correctly by showing Foo and Bar and not showing Baz.
Observe the console and understand the id="foo" node is accessible but the id="bar" and id="baz" elements are not. And this is my problem.
How can I access those nodes imperatively?
http://jsbin.com/kemoravote/1/edit?html,console,output
<!doctype html>
<head>
<meta charset="utf-8">
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="polymer/polymer.html" rel="import">
<link href="iron-form/iron-form.html" rel="import">
</head>
<body>
<dom-module id="x-element">
<template>
<style></style>
<div id="foo">Foo</div>
<template is="dom-if" if="{{show}}">
<div id="bar">Bar</div>
</template>
<template is="dom-if" if="{{!show}}">
<div id="baz">Baz</div>
</template>
</template>
<script>
(function(){
Polymer({
is: "x-element",
properties: {
show: {
type: Boolean,
value: function() {
return true;
}
}
},
attached: function() {
console.log('foo', !!this.$.foo);
console.log('bar', !!this.$.bar);
console.log('baz', !!this.$.baz);
},
});
})();
</script>
</dom-module>
<x-element></x-element>
</body>
The $ selector won't work. You have to use $$ as follows:
console.log('baz', !!this.$$('#baz'));
Here is the jsBin.
http://jsbin.com/xogediyato/1/edit?html,console,output
<!doctype html>
<head>
<meta charset="utf-8">
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="polymer/polymer.html" rel="import">
<link href="iron-form/iron-form.html" rel="import">
</head>
<body>
<dom-module id="x-element">
<template>
<style></style>
<div id="foo">Foo</div>
<template is="dom-if" if="{{show}}">
<div id="bar">Bar</div>
</template>
<template is="dom-if" if="{{!show}}">
<div id="baz">Baz</div>
</template>
</template>
<script>
(function(){
Polymer({
is: "x-element",
properties: {
show: {
type: Boolean,
value: function() {
return true;
}
}
},
attached: function() {
console.log('foo', !!this.$.foo);
console.log('bar', !!this.$.bar);
console.log('baz', !!this.$.baz);
console.log('bar', !!this.$$('#bar'));
console.log('baz', !!this.$$('#baz'));
},
});
})();
</script>
</dom-module>
<x-element></x-element>
</body>

Setting the height of core-pages elements?

I'm having a lot of trouble getting a core-pages element to have a non-zero height within my custom element. What is the best practice for having the core-pages height be the same as its selected content. Here's a trivial example which clearly breaks:
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Polymer</title>
</head>
<body>
<script src="http://www.polymer-project.org/platform.js"></script>
<link rel="import" href="http://www.polymer-project.org/components/polymer/polymer.html">
<link rel="import" href="http://www.polymer-project.org/components/core-pages/core-pages.html">
<polymer-element name="x-foo">
<template>
<core-pages id="pages" selected="{{selected}}">
<content></content>
</core-pages>
</template>
<script>
Polymer('x-foo', {
ready: function() {
this.selected = 0;
}
});
</script>
</polymer-element>
<polymer-element name="x-bar">
<template>
<div><content></content></div>
</template>
<script>
Polymer('x-bar', {});
</script>
</polymer-element>
<p>BEFORE</p>
<x-foo>
<x-bar>some text here</x-bar>
<x-bar>some other text here</x-bar>
</x-foo>
<p>AFTER</p>
</body>
</html>
And the jsbin to see the results: http://jsbin.com/xowoxakuwu/1/edit (notice how the core pages content overlaps with the next element)
This example shows a core-pages element within a custom element. The content that gets injected into the core-pages are also custom elements.
Whats the best practice here?
You can apply a style to the currently selected page in the x-foo element which sets display: block and position: relative so x-bar will inherit the height of it's content.
I've also added the "block" attribute to the x-foo element so it too inherits the height of the selected page. Other general attributes are here -> https://www.polymer-project.org/docs/polymer/layout-attrs.html#general-purpose-attributes
<script src="http://www.polymer-project.org/platform.js"></script>
<link rel="import" href="http://www.polymer-project.org/components/polymer/polymer.html">
<link rel="import" href="http://www.polymer-project.org/components/core-pages/core-pages.html">
<polymer-element name="x-foo" block>
<template>
<style>
::content > .core-selected {
position: relative;
display: block;
}
</style>
<core-pages id="pages" selected="{{selected}}">
<content></content>
</core-pages>
</template>
<script>
Polymer('x-foo', {
ready: function() {
this.selected = 0;
}
});
</script>
</polymer-element>
<polymer-element name="x-bar">
<template>
<div>
<content></content>
</div>
</template>
<script>
Polymer('x-bar', {});
</script>
</polymer-element>
<p>BEFORE</p>
<x-foo>
<x-bar>some text here</x-bar>
<x-bar>some other text here</x-bar>
</x-foo>
<p>AFTER</p>