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>
Related
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>
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
I have a paper-badge with an icon attribute set. I am able to change the size of the badge, but I also want to change the size of the icon inside it.
How can I do that? Thanks
The <paper-badge> currently doesn't support CSS properties to modify the icon's size (it's hard-coded to 12x12). However, you could change icon's size in JavaScript by selecting the badge's <iron-icon> and setting its style.width and style.height:
// template
<paper-badge id="badge"></paper-badge>
// script
const icon = this.$.badge.$$('iron-icon');
icon.style.width = '20px';
icon.style.height = '20px';
HTMLImports.whenReady(() => {
Polymer({
is: 'x-foo',
attached: function() {
const icon = this.$.badge.$$('iron-icon');
icon.style.width = '20px';
icon.style.height = '20px';
}
});
});
<head>
<base href="https://polygit.org/polymer+1.7.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="paper-button/paper-button.html">
<link rel="import" href="paper-badge/paper-badge.html">
<link rel="import" href="iron-icons/iron-icons.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<template>
<style>
paper-badge {
--paper-badge-margin-bottom: -40px;
}
</style>
<div>
<paper-button id="btn">Status</paper-button>
<paper-badge id="badge" icon="favorite" for="btn" label="favorite icon"></paper-badge>
</div>
</template>
</dom-module>
</body>
I have a paper-dialog that uses the with-backdrop property. I've noticed that after clicking anywhere within a paper-dialog that does not use the with-backdrop property, I can hit the tab key and the browser will focus the input element:
addEventListener('WebComponentsReady', function() {
Polymer({
is: 'x-example',
ready: function() {
this.$$('paper-dialog').open();
}
});
});
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="paper-dialog/paper-dialog.html" rel="import">
<link href="paper-input/paper-input.html" rel="import">
<link href="polymer/polymer.html" rel="import">
<dom-module id="x-example">
<style>
:host {
display: block;
}
</style>
<template>
<paper-dialog>
<h2 class="header">Hello</h2>
<paper-input
label="Focusable input"
tabindex
type="text">
</paper-input>
</paper-dialog>
</template>
</dom-module>
<x-example></x-example>
If I set the with-backdrop property, however, the browser will not focus the input element:
addEventListener('WebComponentsReady', function() {
Polymer({
is: 'x-example',
ready: function() {
this.$$('paper-dialog').open();
}
});
});
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="paper-dialog/paper-dialog.html" rel="import">
<link href="paper-input/paper-input.html" rel="import">
<link href="polymer/polymer.html" rel="import">
<dom-module id="x-example">
<style>
:host {
display: block;
}
</style>
<template>
<paper-dialog with-backdrop>
<h2 class="header">Hello</h2>
<paper-input
label="Focusable input"
tabindex
type="text">
</paper-input>
</paper-dialog>
</template>
</dom-module>
<x-example></x-example>
Is there a way to have a backdrop and still allow the dialog to navigatable via the keyboard?
Device info: I am experiencing this issue running Chrome v50 on OSX.
Seems to be issue with versions that you are using. I tried it on Polymer's website and my local and this seems to be working fine. Below are the versions that i used:
Paper-dialog: 1.0.4
Polymer: 1.3.2
Paper-input: 1.0.18
I'll also recommend you to open up an issue on Github for the same
In the demo, I included the tabindex attribute in my input element without specifying a value. Removing this property allowed the input to be focused:
addEventListener('WebComponentsReady', function() {
Polymer({
is: 'x-example',
ready: function() {
this.$$('paper-dialog').open();
}
});
});
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="paper-dialog/paper-dialog.html" rel="import">
<link href="paper-input/paper-input.html" rel="import">
<link href="polymer/polymer.html" rel="import">
<dom-module id="x-example">
<style>
:host {
display: block;
}
</style>
<template>
<paper-dialog with-backdrop>
<h2 class="header">Hello</h2>
<paper-input
label="Focusable input"
type="text">
</paper-input>
</paper-dialog>
</template>
</dom-module>
<x-example></x-example>
with Polymer it's easy to extend another web component. You can use <shadow> to mark the place in the child's template where the shadow dom of the Parent should be (polymer docs).
I'm looking to extend an element, but in a way that a specific part of child gets wrapped by the parent. This kind of setup I've used with some template engines. Can this be done with html includes?
Parent ::
<link rel="import" href="/bower_components/polymer/polymer.html">
<polymer-element name="tpl-parent" noscript>
<template>
<section>
<content></content><!-- put the child template here -->
</section>
</template>
</polymer-element>
Child ::
<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="parent.html">
<polymer-element name="tpl-child" extends="tpl-parent" noscript>
<template>
<shadow>
<p>whatever I put here should be "wrapped" by the _section_ in parent</p>
</shadow>
</template>
</polymer-element>
You can't do it declaratively like that. But I think you can leverage automatic node finding to move a child into the parent's section if it has an id.
<polymer-element name="x-foo">
<template>
<style>
#wrapper p { color: red; }
</style>
<section id="wrapper">
<p>Hello from x-foo</p>
</section>
</template>
<script>
Polymer({
});
</script>
</polymer-element>
<polymer-element name="x-bar" extends="x-foo">
<template>
<p id="foo">I was wrapped by x-foo</p>
<p>I was not wrapped</p>
<shadow></shadow>
</template>
<script>
Polymer({
domReady: function() {
this.$.wrapper.appendChild(this.$.foo);
}
});
</script>
</polymer-element>
<x-bar></x-bar>
Even though #robdodson's answer is completely correct, it kind of feels.. too "loose".
When discussing this further at work, somebody noted the principle of "Composition over inheritance". This led to me viewing this situation from a different (and I think better) perspective.
I ended up with this (also includes an example of passing arguments):
-- x-foo.html
<polymer-element name="x-foo" arguments="status">
<template>
<style>
#wrapper.valid ::content p { color: green; }
#wrapper.invalid ::content p { color: red; }
</style>
<section id="wrapper">
<p>x-bar will be put in the content tag below</p>
<content></content>
</section>
</template>
<script>
Polymer({
status: '',
statusChanged: function(oldVal, newVal) {
if (['valid', 'invalid'].indexOf(newVAl) === -1) {
this.$.wrapper.setAttribute('class', newVal);
}
}
});
</script>
</polymer-element>
-- x-bar.html
<link rel="import" href="x-foo.html" arguments="status">
<polymer-element name="x-bar">
<template>
<x-foo status="{{status}}">
<p>color me</p>
</x-foo>
</template>
<script>
Polymer();
</script>
</polymer-element>
-- index.html
<link rel="import" href="x-bar.html" arguments="status">
<x-bar></x-bar>
The only "disadvantage" is you have to pass on "status". But this feels better then having to append to a "floating" div#wrapper in the super class