<!doctype html>
<!--
Copyright 2013 The Polymer Authors. All rights reserved.
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file.
-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>paper-dropdown-menu</title>
<script src="/www.polymer-project.org/components/polymer.js"></script>
<link rel="import" href="//www.polymer-project.org/components/polymer/polymer.html">
<link rel="import" href="//www.polymer-project.org/components/font-roboto/font-roboto.html">
<link rel="import" href="//www.polymer-project.org/components/paper-item/paper-item.html">
<link rel="import" href="paper-dropdown-menu.html">
<link rel="import" href="//www.polymer-project.org/components/core-collapse/core-collapse.html">
<style shim-shadowdom>
html, body {
font-family: Roboto, 'Helvetica Neue', Helvetica, Arial;
height: 100%;
margin: 0;
}
dropdown-demo {
display: block;
}
dropdown-demo::shadow > section {
padding: 12px;
}
body /deep/ paper-dropdown-menu.narrow {
max-width: 100px;
}
</style>
</head>
<body unresolved>
<dropdown-demo fit></dropdown-demo>
<polymer-element name="dropdown-demo" on-core-select="{{selectAction}}">
<template>
<section layout horizontal>
<!--
<paper-dropdown-menu label="No Collapse">
<template repeat="{{countries}}">
<paper-item label="{{name}}"></paper-item>
</template>
</paper-dropdown-menu>
-->
<div flex></div>
<core-collapse opened=true>
<paper-dropdown-menu-github label="Collapse without overlay" halign="right">
<template repeat="{{countries}}">
<paper-item label="{{name}}"></paper-item>
</template>
</paper-dropdown-menu-github>
</core-collapse>
<div flex></div>
<core-collapse opened=true>
<paper-dropdown-menu-github label="Collapse with overlay" layered=true halign="right">
<template repeat="{{countries}}">
<paper-item label="{{name}}"></paper-item>
</template>
</paper-dropdown-menu-github>
</core-collapse>
</section>
</template>
<script>
Polymer('dropdown-demo', {
countries: [
{name: 'Afghanistan', code: 'AF'},
{name: 'Ă…land Islands', code: 'AX'},
{name: 'Albania', code: 'AL'},
{name: 'Algeria', code: 'DZ'},
{name: 'American Samoa', code: 'AS'},
{name: 'Andorra', code: 'AD'},
{name: 'Angola', code: 'AO'},
{name: 'Anguilla', code: 'AI'},
{name: 'Antarctica', code: 'AQ'},
{name: 'Antigua and Barbuda', code: 'AG'},
{name: 'Argentina', code: 'AR'},
{name: 'Armenia', code: 'AM'},
{name: 'Aruba', code: 'AW'},
{name: 'Australia', code: 'AU'},
{name: 'Austria', code: 'AT'},
{name: 'Azerbaijan', code: 'AZ'},
{name: 'Bahamas', code: 'BS'},
{name: 'Bahrain', code: 'BH'},
{name: 'Bangladesh', code: 'BD'},
{name: 'Barbados', code: 'BB'},
{name: 'Belarus', code: 'BY'},
{name: 'Belgium', code: 'BE'},
{name: 'Belize', code: 'BZ'},
{name: 'Benin', code: 'BJ'},
{name: 'Bermuda', code: 'BM'},
{name: 'Bhutan', code: 'BT'},
{name: 'Bolivia', code: 'BO'},
{name: 'Bosnia and Herzegovina', code: 'BA'},
{name: 'Botswana', code: 'BW'},
{name: 'Bouvet Island', code: 'BV'},
{name: 'Brazil', code: 'BR'},
{name: 'British Indian Ocean Territory', code: 'IO'},
{name: 'Brunei Darussalam', code: 'BN'},
{name: 'Bulgaria', code: 'BG'},
{name: 'Burkina Faso', code: 'BF'},
{name: 'Burundi', code: 'BI'},
{name: 'Cambodia', code: 'KH'},
{name: 'Cameroon', code: 'CM'},
{name: 'Canada', code: 'CA'},
{name: 'Cape Verde', code: 'CV'},
{name: 'Cayman Islands', code: 'KY'},
{name: 'Central African Republic', code: 'CF'},
{name: 'Chad', code: 'TD'},
{name: 'Chile', code: 'CL'},
{name: 'China', code: 'CN'},
{name: 'Christmas Island', code: 'CX'},
{name: 'Cocos (Keeling) Islands', code: 'CC'},
{name: 'Colombia', code: 'CO'},
{name: 'Comoros', code: 'KM'},
{name: 'Congo', code: 'CG'},
{name: 'Congo, The Democratic Republic of the', code: 'CD'},
{name: 'Cook Islands', code: 'CK'},
{name: 'Costa Rica', code: 'CR'},
{name: 'Cote D\'Ivoire', code: 'CI'},
{name: 'Croatia', code: 'HR'},
{name: 'Cuba', code: 'CU'},
{name: 'Cyprus', code: 'CY'},
{name: 'Czech Republic', code: 'CZ'},
{name: 'Denmark', code: 'DK'},
{name: 'Djibouti', code: 'DJ'},
{name: 'Dominica', code: 'DM'},
{name: 'Dominican Republic', code: 'DO'},
{name: 'Ecuador', code: 'EC'},
{name: 'Egypt', code: 'EG'},
{name: 'El Salvador', code: 'SV'},
{name: 'Equatorial Guinea', code: 'GQ'},
{name: 'Eritrea', code: 'ER'},
{name: 'Estonia', code: 'EE'},
{name: 'Ethiopia', code: 'ET'},
{name: 'Falkland Islands (Malvinas)', code: 'FK'},
{name: 'Faroe Islands', code: 'FO'},
{name: 'Fiji', code: 'FJ'},
{name: 'Finland', code: 'FI'},
{name: 'France', code: 'FR'},
{name: 'French Guiana', code: 'GF'},
{name: 'French Polynesia', code: 'PF'},
{name: 'French Southern Territories', code: 'TF'},
{name: 'Gabon', code: 'GA'},
{name: 'Gambia', code: 'GM'},
{name: 'Georgia', code: 'GE'},
{name: 'Germany', code: 'DE'},
{name: 'Ghana', code: 'GH'},
{name: 'Gibraltar', code: 'GI'},
{name: 'Greece', code: 'GR'},
{name: 'Greenland', code: 'GL'},
{name: 'Grenada', code: 'GD'},
{name: 'Guadeloupe', code: 'GP'},
{name: 'Guam', code: 'GU'},
{name: 'Guatemala', code: 'GT'},
{name: 'Guernsey', code: 'GG'},
{name: 'Guinea', code: 'GN'},
{name: 'Guinea-Bissau', code: 'GW'},
{name: 'Guyana', code: 'GY'},
{name: 'Haiti', code: 'HT'},
{name: 'Heard Island and Mcdonald Islands', code: 'HM'},
{name: 'Holy See (Vatican City State)', code: 'VA'},
{name: 'Honduras', code: 'HN'},
{name: 'Hong Kong', code: 'HK'},
{name: 'Hungary', code: 'HU'},
{name: 'Iceland', code: 'IS'},
{name: 'India', code: 'IN'},
{name: 'Indonesia', code: 'ID'},
{name: 'Iran, Islamic Republic Of', code: 'IR'},
{name: 'Iraq', code: 'IQ'},
{name: 'Ireland', code: 'IE'},
{name: 'Isle of Man', code: 'IM'},
{name: 'Israel', code: 'IL'},
{name: 'Italy', code: 'IT'},
{name: 'Jamaica', code: 'JM'},
{name: 'Japan', code: 'JP'},
{name: 'Jersey', code: 'JE'},
{name: 'Jordan', code: 'JO'},
{name: 'Kazakhstan', code: 'KZ'},
{name: 'Kenya', code: 'KE'},
{name: 'Kiribati', code: 'KI'},
{name: 'Korea, Democratic People\'S Republic of', code: 'KP'},
{name: 'Korea, Republic of', code: 'KR'},
{name: 'Kuwait', code: 'KW'},
{name: 'Kyrgyzstan', code: 'KG'},
{name: 'Lao People\'S Democratic Republic', code: 'LA'},
{name: 'Latvia', code: 'LV'},
{name: 'Lebanon', code: 'LB'},
{name: 'Lesotho', code: 'LS'},
{name: 'Liberia', code: 'LR'},
{name: 'Libyan Arab Jamahiriya', code: 'LY'},
{name: 'Liechtenstein', code: 'LI'},
{name: 'Lithuania', code: 'LT'},
{name: 'Luxembourg', code: 'LU'},
{name: 'Macao', code: 'MO'},
{name: 'Macedonia, The Former Yugoslav Republic of', code: 'MK'},
{name: 'Madagascar', code: 'MG'},
{name: 'Malawi', code: 'MW'},
{name: 'Malaysia', code: 'MY'},
{name: 'Maldives', code: 'MV'},
{name: 'Mali', code: 'ML'},
{name: 'Malta', code: 'MT'},
{name: 'Marshall Islands', code: 'MH'},
{name: 'Martinique', code: 'MQ'},
{name: 'Mauritania', code: 'MR'},
{name: 'Mauritius', code: 'MU'},
{name: 'Mayotte', code: 'YT'},
{name: 'Mexico', code: 'MX'},
{name: 'Micronesia, Federated States of', code: 'FM'},
{name: 'Moldova, Republic of', code: 'MD'},
{name: 'Monaco', code: 'MC'},
{name: 'Mongolia', code: 'MN'},
{name: 'Montserrat', code: 'MS'},
{name: 'Morocco', code: 'MA'},
{name: 'Mozambique', code: 'MZ'},
{name: 'Myanmar', code: 'MM'},
{name: 'Namibia', code: 'NA'},
{name: 'Nauru', code: 'NR'},
{name: 'Nepal', code: 'NP'},
{name: 'Netherlands', code: 'NL'},
{name: 'Netherlands Antilles', code: 'AN'},
{name: 'New Caledonia', code: 'NC'},
{name: 'New Zealand', code: 'NZ'},
{name: 'Nicaragua', code: 'NI'},
{name: 'Niger', code: 'NE'},
{name: 'Nigeria', code: 'NG'},
{name: 'Niue', code: 'NU'},
{name: 'Norfolk Island', code: 'NF'},
{name: 'Northern Mariana Islands', code: 'MP'},
{name: 'Norway', code: 'NO'},
{name: 'Oman', code: 'OM'},
{name: 'Pakistan', code: 'PK'},
{name: 'Palau', code: 'PW'},
{name: 'Palestinian Territory, Occupied', code: 'PS'},
{name: 'Panama', code: 'PA'},
{name: 'Papua New Guinea', code: 'PG'},
{name: 'Paraguay', code: 'PY'},
{name: 'Peru', code: 'PE'},
{name: 'Philippines', code: 'PH'},
{name: 'Pitcairn', code: 'PN'},
{name: 'Poland', code: 'PL'},
{name: 'Portugal', code: 'PT'},
{name: 'Puerto Rico', code: 'PR'},
{name: 'Qatar', code: 'QA'},
{name: 'Reunion', code: 'RE'},
{name: 'Romania', code: 'RO'},
{name: 'Russian Federation', code: 'RU'},
{name: 'RWANDA', code: 'RW'},
{name: 'Saint Helena', code: 'SH'},
{name: 'Saint Kitts and Nevis', code: 'KN'},
{name: 'Saint Lucia', code: 'LC'},
{name: 'Saint Pierre and Miquelon', code: 'PM'},
{name: 'Saint Vincent and the Grenadines', code: 'VC'},
{name: 'Samoa', code: 'WS'},
{name: 'San Marino', code: 'SM'},
{name: 'Sao Tome and Principe', code: 'ST'},
{name: 'Saudi Arabia', code: 'SA'},
{name: 'Senegal', code: 'SN'},
{name: 'Serbia and Montenegro', code: 'CS'},
{name: 'Seychelles', code: 'SC'},
{name: 'Sierra Leone', code: 'SL'},
{name: 'Singapore', code: 'SG'},
{name: 'Slovakia', code: 'SK'},
{name: 'Slovenia', code: 'SI'},
{name: 'Solomon Islands', code: 'SB'},
{name: 'Somalia', code: 'SO'},
{name: 'South Africa', code: 'ZA'},
{name: 'South Georgia and the South Sandwich Islands', code: 'GS'},
{name: 'Spain', code: 'ES'},
{name: 'Sri Lanka', code: 'LK'},
{name: 'Sudan', code: 'SD'},
{name: 'Suriname', code: 'SR'},
{name: 'Svalbard and Jan Mayen', code: 'SJ'},
{name: 'Swaziland', code: 'SZ'},
{name: 'Sweden', code: 'SE'},
{name: 'Switzerland', code: 'CH'},
{name: 'Syrian Arab Republic', code: 'SY'},
{name: 'Taiwan, Province of China', code: 'TW'},
{name: 'Tajikistan', code: 'TJ'},
{name: 'Tanzania, United Republic of', code: 'TZ'},
{name: 'Thailand', code: 'TH'},
{name: 'Timor-Leste', code: 'TL'},
{name: 'Togo', code: 'TG'},
{name: 'Tokelau', code: 'TK'},
{name: 'Tonga', code: 'TO'},
{name: 'Trinidad and Tobago', code: 'TT'},
{name: 'Tunisia', code: 'TN'},
{name: 'Turkey', code: 'TR'},
{name: 'Turkmenistan', code: 'TM'},
{name: 'Turks and Caicos Islands', code: 'TC'},
{name: 'Tuvalu', code: 'TV'},
{name: 'Uganda', code: 'UG'},
{name: 'Ukraine', code: 'UA'},
{name: 'United Arab Emirates', code: 'AE'},
{name: 'United Kingdom', code: 'GB'},
{name: 'United States', code: 'US'},
{name: 'United States Minor Outlying Islands', code: 'UM'},
{name: 'Uruguay', code: 'UY'},
{name: 'Uzbekistan', code: 'UZ'},
{name: 'Vanuatu', code: 'VU'},
{name: 'Venezuela', code: 'VE'},
{name: 'Viet Nam', code: 'VN'},
{name: 'Virgin Islands, British', code: 'VG'},
{name: 'Virgin Islands, U.S.', code: 'VI'},
{name: 'Wallis and Futuna', code: 'WF'},
{name: 'Western Sahara', code: 'EH'},
{name: 'Yemen', code: 'YE'},
{name: 'Zambia', code: 'ZM'},
{name: 'Zimbabwe', code: 'ZW'}
],
selectAction: function(e, details) {
console.log('select', details.selected, details.item);
}
});
</script>
</polymer-element>
</body>
</html>
<!--
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<!--
`paper-dropdown-menu` is a control where the user can choose from an array of
options in a drop-down menu. The currently selected option is displayed in
the control.
Example:
<paper-dropdown-menu selected="Financier" valueattr="label">
<paper-item label="Croissant"></paper-item>
<paper-item label="Donut"></paper-item>
<paper-item label="Financier"></paper-item>
<paper-item label="Madeleine"></paper-item>
</paper-dropdown-menu>
This example renders a drop-down menu with 4 options, with the option
`Financier` pre-selected.
Theming
-------
Style the drop-down menu with the `paper-dropdown-menu::shadow #menu` selector.
Example:
paper-dropdown-menu::shadow #dropdown {
background-color: #eee;
border: 1px solid #ccc;
}
@group Paper Elements
@element paper-dropdown-menu
@status beta
@homepage github.io
-->
<!--
Fired when an item's selection state is changed. This event is fired both
when an item is selected or deselected. The `isSelected` detail property
contains the selection state.
@event core-select
@param {Object} detail
@param {boolean} detail.isSelected true for selection and false for deselection
@param {Object} detail.item the item element
-->
<link href="//www.polymer-project.org/components/polymer/polymer.html" rel="import">
<link href="core-dropdown.html" rel="import">
<link href="//www.polymer-project.org/components/core-icon/core-icon.html" rel="import">
<link href="//www.polymer-project.org/components/core-icons/core-icons.html" rel="import">
<link href="//www.polymer-project.org/components/core-menu/core-menu.html" rel="import">
<link href="//www.polymer-project.org/components/paper-shadow/paper-shadow.html" rel="import">
<style shim-shadowdom>
html /deep/ #paper-dropdown-menu-dropdown {
margin: 12px;
overflow: visible;
}
html /deep/ #paper-dropdown-menu-dropdown #menu {
padding: 8px 0;
margin: 0;
}
html /deep/ #paper-dropdown-menu-dropdown .menu-container {
overflow: auto;
max-height: 100%;
max-width: 100%;
}
</style>
<polymer-element name="paper-dropdown-menu-github">
<template>
<link href="paper-dropdown-menu.css" rel="stylesheet">
<div id="control" layout horizontal selected?="{{selectedItem}}" on-tap="{{toggle}}">
<div flex>
{{selectedItem ? (selectedItem.label || selected) : label}}
</div>
<core-icon id="arrow" icon="{{opened ? 'arrow-drop-up' : 'arrow-drop-down'}}"></core-icon>
</div>
<core-dropdown id="paper-dropdown-menu-dropdown" relatedTarget="{{$.control}}" opened="{{opened}}" halign="{{halign}}" valign="{{valign}}" layered="{{layered}}">
<paper-shadow fit></paper-shadow>
<div class="menu-container">
<core-menu id="menu" selected="{{selected}}" selectedItem="{{selectedItem}}" selectedClass="{{selectedClass}}" valueattr="{{valueattr}}" selectedProperty="{{selectedProperty}}" selectedAttribute="{{selectedAttribute}}" on-core-activate="{{activateAction}}">
<content></content>
</core-menu>
</div>
</core-dropdown>
</template>
<script>
Polymer({
publish: {
/**
* True if the menu is open.
*
* @attribute opened
* @type boolean
* @default false
*/
opened: false,
/**
* A label for the control. The label is displayed if no item is selected.
*
* @attribute label
* @type string
* @default 'Select an item'
*/
label: 'Select an item',
/**
* The currently selected element. By default this is the index of the item element.
* If you want a specific attribute value of the element to be used instead of the
* index, set `valueattr` to that attribute name.
*
* @attribute selected
* @type Object
* @default null
*/
selected: null,
/**
* Specifies the attribute to be used for "selected" attribute.
*
* @attribute valueattr
* @type string
* @default 'name'
*/
valueattr: 'name',
/**
* Specifies the CSS class to be used to add to the selected element.
*
* @attribute selectedClass
* @type string
* @default 'core-selected'
*/
selectedClass: 'core-selected',
/**
* Specifies the property to be used to set on the selected element
* to indicate its active state.
*
* @attribute selectedProperty
* @type string
* @default ''
*/
selectedProperty: '',
/**
* Specifies the attribute to set on the selected element to indicate
* its active state.
*
* @attribute selectedAttribute
* @type string
* @default 'active'
*/
selectedAttribute: 'selected',
/**
* The currently selected element.
*
* @attribute selectedItem
* @type Object
* @default null
*/
selectedItem: null,
/**
* If true, the overlay is guaranteed to display above page content.
*
* @attribute layered
* @type boolean
* @default false
*/
layered: false,
/**
* Horizontally align the overlay with the control.
* @attribute halign
* @type "left"|"right"
* @default "left"
*/
halign: 'left',
/**
* Vertically align the dropdown menu with the control.
* @attribute valign
* @type "top"|"bottom"
* @default "top"
*/
valign: 'top'
},
toggle: function() {
this.opened = !this.opened;
},
activateAction: function() {
this.opened = false;
}
});
</script>
</polymer-element>
/*
* @license
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
:host {
position: relative;
display: inline-block;
background-color: #fff;
-moz-user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
user-select: none;
cursor: pointer;
padding: 0.75em 0;
}
#control {
box-sizing: border-box;
max-height: 2em;
color: #757575;
border-bottom: 1px solid #757575;
}
#control[selected] {
color: #000;
}
#control > div {
padding: 0.5em 0 0.25em;
overflow: hidden;
/* FIXME not working for some reason */
white-space: nowrap;
text-overflow: ellipsis;
}
core-icon {
margin: 0.3em 0 0.2em 0.25em;
}
<!--
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<!--
`core-dropdown` is an element that is initially hidden and is positioned relatively to another
element, usually the element that triggers the dropdown. The dropdown and the triggering element
should be children of the same offsetParent, e.g. the same `<div>` with `position: relative`.
It can be used to implement dropdown menus, menu buttons, etc..
Example:
<template is="auto-binding">
<div relative>
<core-icon-button id="trigger" icon="menu"></core-icon-button>
<core-dropdown relatedTarget="{{$.trigger}}">
<core-menu>
<core-item>Cut</core-item>
<core-item>Copy</core-item>
<core-item>Paste</core-item>
</core-menu>
</core-dropdown>
</div>
</template>
Positioning
-----------
By default, the dropdown is absolutely positioned on top of the `relatedTarget` with the top and
left edges aligned. The `halign` and `valign` properties controls the various alignments. The size
of the dropdown is automatically restrained such that it is entirely visible on the screen. Use the
`margin`
If you need more control over the dropdown's position, use CSS. The `halign` and `valign` properties are
ignored if the dropdown is positioned with CSS.
Example:
<style>
/* manually position the dropdown below the trigger */
core-dropdown {
position: absolute;
top: 38px;
left: 0;
}
</style>
<template is="auto-binding">
<div relative>
<core-icon-button id="trigger" icon="menu"></core-icon-button>
<core-dropdown relatedTarget="{{$.trigger}}">
<core-menu>
<core-item>Cut</core-item>
<core-item>Copy</core-item>
<core-item>Paste</core-item>
</core-menu>
</core-dropdown>
</div>
</template>
The `layered` property
----------------------
Sometimes you may need to render the dropdown in a separate layer. For example,
it may be nested inside an element that needs to be `overflow: hidden`, or
its parent may be overlapped by elements above it in stacking order.
The `layered` property will place the dropdown in a separate layer to ensure
it appears on top of everything else. Note that this implies the dropdown will
not scroll with its container.
@group Polymer Core Elements
@element core-dropdown
@homepage github.io
-->
<link href="//www.polymer-project.org/components/polymer/polymer.html" rel="import">
<link href="core-overlay.html" rel="import">
<style>
html /deep/ core-dropdown {
position: absolute;
overflow: auto;
background-color: #fff;
}
</style>
<polymer-element name="core-dropdown" extends="core-overlay">
<script>
Polymer({
publish: {
/**
* The element associated with this dropdown, usually the element that triggers
* the menu.
*
* @attribute relatedTarget
* @type Node
*/
relatedTarget: null,
/**
* The horizontal alignment of the popup relative to `relatedTarget`. `left`
* means the left edges are aligned together. `right` means the right edges
* are aligned together.
*
* @attribute halign
* @type 'left' | 'right'
* @default 'left'
*/
halign: 'left',
/**
* The vertical alignment of the popup relative to `relatedTarget`. `top` means
* the top edges are aligned together. `bottom` means the bottom edges are
* aligned together.
*
* @attribute valign
* @type 'top' | 'bottom'
* @default 'top'
*/
valign: 'top',
},
measure: function() {
var target = this.target;
// remember position, because core-overlay may have set the property
var pos = target.style.position;
// get the size of the target as if it's positioned in the top left
// corner of the screen
target.style.position = 'fixed';
target.style.left = '0px';
target.style.top = '0px';
var rect = target.getBoundingClientRect();
target.style.position = pos;
target.style.left = null;
target.style.top = null;
return rect;
},
resetTargetDimensions: function() {
var dims = this.dimensions;
var style = this.target.style;
if (dims.position.h_by === this.localName) {
style[dims.position.h] = null;
dims.position.h_by = null;
}
if (dims.position.v_by === this.localName) {
style[dims.position.v] = null;
dims.position.v_by = null;
}
this.super();
},
positionTarget: function() {
if (!this.relatedTarget) {
this.super();
return;
}
// explicitly set width/height, because we don't want it constrained
// to the offsetParent
var target = this.target;
var rect = this.measure();
target.style.width = rect.width + 'px';
target.style.height = rect.height + 'px';
if (this.layered) {
this.positionLayeredTarget();
} else {
this.positionNestedTarget();
}
},
positionLayeredTarget: function() {
var target = this.target;
var rect = this.relatedTarget.getBoundingClientRect();
var dims = this.dimensions;
var margin = dims.margin;
if (!dims.position.h) {
if (this.halign === 'right') {
target.style.right = window.innerWidth - rect.right - margin.right + 'px';
dims.position.h = 'right';
} else {
target.style.left = rect.left - margin.left + 'px';
dims.position.h = 'left';
}
dims.position.h_by = this.localName;
}
if (!dims.position.v) {
if (this.valign === 'bottom') {
target.style.bottom = window.innerHeight - rect.bottom - margin.bottom + 'px';
dims.position.v = 'bottom';
} else {
target.style.top = rect.top - margin.top + 'px';
dims.position.v = 'top';
}
dims.position.v_by = this.localName;
}
if (dims.position.h_by || dims.position.v_by) {
target.style.position = 'fixed';
}
},
positionNestedTarget: function() {
var target = this.target;
var related = this.relatedTarget;
var t_op = target.offsetParent;
var r_op = related.offsetParent;
if (window.ShadowDOMPolyfill) {
t_op = wrap(t_op);
r_op = wrap(r_op);
}
if (t_op !== r_op && t_op !== related) {
console.warn('core-dropdown-overlay: dropdown\'s offsetParent must be the relatedTarget or the relatedTarget\'s offsetParent!');
}
// Don't use CSS to handle halign/valign so we can use
// dimensions.position to detect custom positioning
var dims = this.dimensions;
var margin = dims.margin;
var inside = t_op === related;
if (!dims.position.h) {
if (this.halign === 'right') {
target.style.right = ((inside ? 0 : t_op.offsetWidth - related.offsetLeft - related.offsetWidth) - margin.right) + 'px';
dims.position.h = 'right';
} else {
target.style.left = ((inside ? 0 : related.offsetLeft) - margin.left) + 'px';
dims.position.h = 'left';
}
dims.position.h_by = this.localName;
}
if (!dims.position.v) {
if (this.valign === 'bottom') {
target.style.bottom = ((inside ? 0 : t_op.offsetHeight - related.offsetTop - related.offsetHeight) - margin.bottom) + 'px';
dims.position.v = 'bottom';
} else {
target.style.top = ((inside ? 0 : related.offsetTop) - margin.top) + 'px';
dims.position.v = 'top';
}
dims.position.v_by = this.localName;
}
}
});
</script>
</polymer-element>
<!--
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<link rel="import" href="//www.polymer-project.org/components/polymer/polymer.html">
<link rel="import" href="//www.polymer-project.org/components/core-transition/core-transition.html">
<link rel="import" href="//www.polymer-project.org/components/core-overlay/core-key-helper.html">
<link rel="import" href="core-overlay-layer.html">
<!--
The `core-overlay` element displays overlayed on top of other content. It starts
out hidden and is displayed by setting its `opened` property to true.
A `core-overlay's` opened state can be toggled by calling the `toggle`
method.
The `core-overlay` will, by default, show/hide itself when it's opened. The
`target` property may be set to another element to cause that element to
be shown when the overlay is opened.
It's common to want a `core-overlay` to animate to its opened
position. The `core-overlay` element uses a `core-transition` to handle
animation. The default transition is `core-transition-fade` which
causes the overlay to fade in when displayed. See
<a href="../core-transition/">`core-transition`</a> for more
information about customizing a `core-overlay's` opening animation. The
`backdrop` property can be set to true to show a backdrop behind the overlay
that will darken the rest of the window.
An element that should close the `core-overlay` will automatically
do so if it's given the `core-overlay-toggle` attribute. This attribute
can be customized with the `closeAttribute` property. You can also use
`closeSelector` if more general matching is needed.
By default `core-overlay` will close whenever the user taps outside it or
presses the escape key. This behavior can be turned off via the
`autoCloseDisabled` property.
<core-overlay>
<h2>Dialog</h2>
<input placeholder="say something..." autofocus>
<div>I agree with this wholeheartedly.</div>
<button core-overlay-toggle>OK</button>
</core-overlay>
`core-overlay` will automatically size and position itself according to the
following rules. The overlay's size is constrained such that it does not
overflow the screen. This is done by setting maxHeight/maxWidth on the
`sizingTarget`. If the `sizingTarget` already has a setting for one of these
properties, it will not be overridden. The overlay should
be positioned via css or imperatively using the `core-overlay-position` event.
If the overlay is not positioned vertically via setting `top` or `bottom`, it
will be centered vertically. The same is true horizontally via a setting to
`left` or `right`. In addition, css `margin` can be used to provide some space
around the overlay. This can be used to ensure
that, for example, a drop shadow is always visible around the overlay.
@group Core Elements
@element core-overlay
@homepage github.io
-->
<!--
Fired when the `core-overlay`'s `opened` property changes.
@event core-overlay-open
@param {Object} detail
@param {Object} detail.opened the opened state
-->
<!--
Fired when the `core-overlay` has completely opened.
@event core-overlay-open-completed
-->
<!--
Fired when the `core-overlay` has completely closed.
@event core-overlay-close-completed
-->
<!--
Fired when the `core-overlay` needs to position itself. Optionally, implement
in order to position an overlay via code. If the overlay was not otherwise
positioned, it's important to indicate how the overlay has been positioned by
setting the `dimensions.position` object. For example, if the overlay has been
positioned via setting `right` and `top`, set dimensions.position to an
object like this: `{v: 'top', h: 'right'}`.
@event core-overlay-position
@param {Object} detail
@param {Object} detail.target the overlay target
@param {Object} detail.sizingTarget the overlay sizing target
@param {Object} detail.opened the opened state
-->
<style>
.core-overlay-backdrop {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: black;
opacity: 0;
transition: opacity 0.2s;
}
.core-overlay-backdrop.core-opened {
opacity: 0.6;
}
</style>
<polymer-element name="core-overlay">
<script>
(function() {
Polymer('core-overlay', {
publish: {
/**
* The target element that will be shown when the overlay is
* opened. If unspecified, the core-overlay itself is the target.
*
* @attribute target
* @type Object
* @default the overlay element
*/
target: null,
/**
* A `core-overlay`'s size is guaranteed to be
* constrained to the window size. To achieve this, the sizingElement
* is sized with a max-height/width. By default this element is the
* target element, but it can be specifically set to a specific element
* inside the target if that is more appropriate. This is useful, for
* example, when a region inside the overlay should scroll if needed.
*
* @attribute sizingTarget
* @type Object
* @default the target element
*/
sizingTarget: null,
/**
* Set opened to true to show an overlay and to false to hide it.
* A `core-overlay` may be made initially opened by setting its
* `opened` attribute.
* @attribute opened
* @type boolean
* @default false
*/
opened: false,
/**
* If true, the overlay has a backdrop darkening the rest of the screen.
* The backdrop element is attached to the document body and may be styled
* with the class `core-overlay-backdrop`. When opened the `core-opened`
* class is applied.
*
* @attribute backdrop
* @type boolean
* @default false
*/
backdrop: false,
/**
* If true, the overlay is guaranteed to display above page content.
*
* @attribute layered
* @type boolean
* @default false
*/
layered: false,
/**
* By default an overlay will close automatically if the user
* taps outside it or presses the escape key. Disable this
* behavior by setting the `autoCloseDisabled` property to true.
* @attribute autoCloseDisabled
* @type boolean
* @default false
*/
autoCloseDisabled: false,
/**
* By default an overlay will focus its target or an element inside
* it with the `autoFocus` attribute. Disable this
* behavior by setting the `autoFocusDisabled` property to true.
* @attribute autoFocusDisabled
* @type boolean
* @default false
*/
autoFocusDisabled: false,
/**
* This property specifies an attribute on elements that should
* close the overlay on tap. Should not set `closeSelector` if this
* is set.
*
* @attribute closeAttribute
* @type string
* @default "core-overlay-toggle"
*/
closeAttribute: 'core-overlay-toggle',
/**
* This property specifies a selector matching elements that should
* close the overlay on tap. Should not set `closeAttribute` if this
* is set.
*
* @attribute closeSelector
* @type string
* @default ""
*/
closeSelector: '',
/**
* The transition property specifies a string which identifies a
* <a href="../core-transition/">`core-transition`</a> element that
* will be used to help the overlay open and close. The default
* `core-transition-fade` will cause the overlay to fade in and out.
*
* @attribute transition
* @type string
* @default 'core-transition-fade'
*/
transition: 'core-transition-fade'
},
captureEventName: 'tap',
targetListeners: {
'tap': 'tapHandler',
'keydown': 'keydownHandler',
'core-transitionend': 'transitionend'
},
registerCallback: function(element) {
this.layer = document.createElement('core-overlay-layer');
this.keyHelper = document.createElement('core-key-helper');
this.meta = document.createElement('core-transition');
this.scrim = document.createElement('div');
this.scrim.className = 'core-overlay-backdrop';
},
ready: function() {
this.target = this.target || this;
// flush to ensure styles are installed before paint
Platform.flush();
},
/**
* Toggle the opened state of the overlay.
* @method toggle
*/
toggle: function() {
this.opened = !this.opened;
},
/**
* Open the overlay. This is equivalent to setting the `opened`
* property to true.
* @method open
*/
open: function() {
this.opened = true;
},
/**
* Close the overlay. This is equivalent to setting the `opened`
* property to false.
* @method close
*/
close: function() {
this.opened = false;
},
domReady: function() {
this.ensureTargetSetup();
},
targetChanged: function(old) {
if (this.target) {
// really make sure tabIndex is set
if (this.target.tabIndex < 0) {
this.target.tabIndex = -1;
}
this.addElementListenerList(this.target, this.targetListeners);
this.target.style.display = 'none';
this.target.__overlaySetup = false;
}
if (old) {
this.removeElementListenerList(old, this.targetListeners);
var transition = this.getTransition();
if (transition) {
transition.teardown(old);
} else {
old.style.position = '';
old.style.outline = '';
}
old.style.display = '';
}
},
transitionChanged: function(old) {
if (!this.target) {
return;
}
if (old) {
this.getTransition(old).teardown(this.target);
}
this.target.__overlaySetup = false;
},
// NOTE: wait to call this until we're as sure as possible that target
// is styled.
ensureTargetSetup: function() {
if (!this.target || this.target.__overlaySetup) {
return;
}
if (!this.sizingTarget) {
this.sizingTarget = this.target;
}
this.target.__overlaySetup = true;
this.target.style.display = '';
var transition = this.getTransition();
if (transition) {
transition.setup(this.target);
}
var style = this.target.style;
var computed = getComputedStyle(this.target);
if (computed.position === 'static') {
style.position = 'fixed';
}
style.outline = 'none';
style.display = 'none';
},
openedChanged: function() {
this.transitioning = true;
this.ensureTargetSetup();
this.prepareRenderOpened();
// async here to allow overlay layer to become visible.
this.async(function() {
this.target.style.display = '';
// force layout to ensure transitions will go
this.target.offsetWidth;
this.renderOpened();
});
this.fire('core-overlay-open', this.opened);
},
// tasks which must occur before opening; e.g. making the element visible
prepareRenderOpened: function() {
if (this.opened) {
addOverlay(this);
}
this.prepareBackdrop();
// async so we don't auto-close immediately via a click.
this.async(function() {
if (!this.autoCloseDisabled) {
this.enableElementListener(this.opened, document,
this.captureEventName, 'captureHandler', true);
}
});
this.enableElementListener(this.opened, window, 'resize',
'resizeHandler');
if (this.opened) {
// force layout so SD Polyfill renders
this.target.offsetHeight;
this.discoverDimensions();
// if we are showing, then take care when positioning
this.preparePositioning();
this.positionTarget();
this.updateTargetDimensions();
this.finishPositioning();
if (this.layered) {
this.layer.addElement(this.target);
this.layer.opened = this.opened;
}
}
},
// tasks which cause the overlay to actually open; typically play an
// animation
renderOpened: function() {
var transition = this.getTransition();
if (transition) {
transition.go(this.target, {opened: this.opened});
} else {
this.transitionend();
}
this.renderBackdropOpened();
},
// finishing tasks; typically called via a transition
transitionend: function(e) {
// make sure this is our transition event.
if (e && e.target !== this.target) {
return;
}
this.transitioning = false;
if (!this.opened) {
this.resetTargetDimensions();
this.target.style.display = 'none';
this.completeBackdrop();
removeOverlay(this);
if (this.layered) {
if (!currentOverlay()) {
this.layer.opened = this.opened;
}
this.layer.removeElement(this.target);
}
}
this.fire('core-overlay-' + (this.opened ? 'open' : 'close') +
'-completed');
this.applyFocus();
},
prepareBackdrop: function() {
if (this.backdrop && this.opened) {
if (!this.scrim.parentNode) {
document.body.appendChild(this.scrim);
this.scrim.style.zIndex = currentOverlayZ() - 1;
}
trackBackdrop(this);
}
},
renderBackdropOpened: function() {
if (this.backdrop && getBackdrops().length < 2) {
this.scrim.classList.toggle('core-opened', this.opened);
}
},
completeBackdrop: function() {
if (this.backdrop) {
trackBackdrop(this);
if (getBackdrops().length === 0) {
this.scrim.parentNode.removeChild(this.scrim);
}
}
},
preparePositioning: function() {
this.target.style.transition = this.target.style.webkitTransition = 'none';
this.target.style.transform = this.target.style.webkitTransform = 'none';
this.target.style.display = '';
},
discoverDimensions: function() {
if (this.dimensions) {
return;
}
var target = getComputedStyle(this.target);
var sizer = getComputedStyle(this.sizingTarget);
this.dimensions = {
position: {
v: target.top !== 'auto' ? 'top' : (target.bottom !== 'auto' ?
'bottom' : null),
h: target.left !== 'auto' ? 'left' : (target.right !== 'auto' ?
'right' : null),
css: target.position
},
size: {
v: sizer.maxHeight !== 'none',
h: sizer.maxWidth !== 'none'
},
margin: {
top: parseInt(target.marginTop) || 0,
right: parseInt(target.marginRight) || 0,
bottom: parseInt(target.marginBottom) || 0,
left: parseInt(target.marginLeft) || 0
}
};
},
finishPositioning: function(target) {
this.target.style.display = 'none';
this.target.style.transform = this.target.style.webkitTransform = '';
// force layout to avoid application of transform
this.target.offsetWidth;
this.target.style.transition = this.target.style.webkitTransition = '';
},
getTransition: function(name) {
return this.meta.byId(name || this.transition);
},
getFocusNode: function() {
return this.target.querySelector('[autofocus]') || this.target;
},
applyFocus: function() {
var focusNode = this.getFocusNode();
if (this.opened) {
if (!this.autoFocusDisabled) {
focusNode.focus();
}
} else {
focusNode.blur();
if (currentOverlay() == this) {
console.warn('Current core-overlay is attempting to focus itself as next! (bug)');
} else {
focusOverlay();
}
}
},
positionTarget: function() {
// fire positioning event
this.fire('core-overlay-position', {target: this.target,
sizingTarget: this.sizingTarget, opened: this.opened});
if (!this.dimensions.position.v) {
this.target.style.top = '0px';
}
if (!this.dimensions.position.h) {
this.target.style.left = '0px';
}
},
updateTargetDimensions: function() {
this.sizeTarget();
this.repositionTarget();
},
sizeTarget: function() {
this.sizingTarget.style.boxSizing = 'border-box';
var dims = this.dimensions;
var rect = this.target.getBoundingClientRect();
if (!dims.size.v) {
this.sizeDimension(rect, dims.position.v, 'top', 'bottom', 'Height');
}
if (!dims.size.h) {
this.sizeDimension(rect, dims.position.h, 'left', 'right', 'Width');
}
},
sizeDimension: function(rect, positionedBy, start, end, extent) {
var dims = this.dimensions;
var flip = (positionedBy === end);
var m = flip ? start : end;
var ws = window['inner' + extent];
var o = dims.margin[m] + (flip ? ws - rect[end] :
rect[start]);
var offset = 'offset' + extent;
var o2 = this.target[offset] - this.sizingTarget[offset];
this.sizingTarget.style['max' + extent] = (ws - o - o2) + 'px';
},
// vertically and horizontally center if not positioned
repositionTarget: function() {
// only center if position fixed.
if (this.dimensions.position.css !== 'fixed') {
return;
}
if (!this.dimensions.position.v) {
var t = (window.innerHeight - this.target.offsetHeight) / 2;
t -= this.dimensions.margin.top;
this.target.style.top = t + 'px';
}
if (!this.dimensions.position.h) {
var l = (window.innerWidth - this.target.offsetWidth) / 2;
l -= this.dimensions.margin.left;
this.target.style.left = l + 'px';
}
},
resetTargetDimensions: function() {
if (!this.dimensions.size.v) {
this.sizingTarget.style.maxHeight = '';
this.target.style.top = '';
}
if (!this.dimensions.size.h) {
this.sizingTarget.style.maxWidth = '';
this.target.style.left = '';
}
this.dimensions = null;
},
tapHandler: function(e) {
// closeSelector takes precedence since closeAttribute has a default non-null value.
if (e.target &&
(this.closeSelector && e.target.matches(this.closeSelector)) ||
(this.closeAttribute && e.target.hasAttribute(this.closeAttribute))) {
this.toggle();
} else {
if (this.autoCloseJob) {
this.autoCloseJob.stop();
this.autoCloseJob = null;
}
}
},
// We use the traditional approach of capturing events on document
// to to determine if the overlay needs to close. However, due to
// ShadowDOM event retargeting, the event target is not useful. Instead
// of using it, we attempt to close asynchronously and prevent the close
// if a tap event is immediately heard on the target.
// TODO(sorvell): This approach will not work with modal. For
// this we need a scrim.
captureHandler: function(e) {
if (!this.autoCloseDisabled && (currentOverlay() == this)) {
this.autoCloseJob = this.job(this.autoCloseJob, function() {
this.close();
});
}
},
keydownHandler: function(e) {
if (!this.autoCloseDisabled && (e.keyCode == this.keyHelper.ESCAPE_KEY)) {
this.close();
e.stopPropagation();
}
},
/**
* Extensions of core-overlay should implement the `resizeHandler`
* method to adjust the size and position of the overlay when the
* browser window resizes.
* @method resizeHandler
*/
resizeHandler: function() {
this.updateTargetDimensions();
},
// TODO(sorvell): these utility methods should not be here.
addElementListenerList: function(node, events) {
for (var i in events) {
this.addElementListener(node, i, events[i]);
}
},
removeElementListenerList: function(node, events) {
for (var i in events) {
this.removeElementListener(node, i, events[i]);
}
},
enableElementListener: function(enable, node, event, methodName, capture) {
if (enable) {
this.addElementListener(node, event, methodName, capture);
} else {
this.removeElementListener(node, event, methodName, capture);
}
},
addElementListener: function(node, event, methodName, capture) {
var fn = this._makeBoundListener(methodName);
if (node && fn) {
Polymer.addEventListener(node, event, fn, capture);
}
},
removeElementListener: function(node, event, methodName, capture) {
var fn = this._makeBoundListener(methodName);
if (node && fn) {
Polymer.removeEventListener(node, event, fn, capture);
}
},
_makeBoundListener: function(methodName) {
var self = this, method = this[methodName];
if (!method) {
return;
}
var bound = '_bound' + methodName;
if (!this[bound]) {
this[bound] = function(e) {
method.call(self, e);
};
}
return this[bound];
},
});
// TODO(sorvell): This should be an element with private state so it can
// be independent of overlay.
// track overlays for z-index and focus managemant
var overlays = [];
function addOverlay(overlay) {
var z0 = currentOverlayZ();
overlays.push(overlay);
var z1 = currentOverlayZ();
if (z1 <= z0) {
applyOverlayZ(overlay, z0);
}
}
function removeOverlay(overlay) {
var i = overlays.indexOf(overlay);
if (i >= 0) {
overlays.splice(i, 1);
setZ(overlay, '');
}
}
function applyOverlayZ(overlay, aboveZ) {
setZ(overlay.target, aboveZ + 2);
}
function setZ(element, z) {
element.style.zIndex = z;
}
function currentOverlay() {
return overlays[overlays.length-1];
}
var DEFAULT_Z = 10;
function currentOverlayZ() {
var z;
var current = currentOverlay();
if (current) {
var z1 = window.getComputedStyle(current.target).zIndex;
if (!isNaN(z1)) {
z = Number(z1);
}
}
return z || DEFAULT_Z;
}
function focusOverlay() {
var current = currentOverlay();
// We have to be careful to focus the next overlay _after_ any current
// transitions are complete (due to the state being toggled prior to the
// transition). Otherwise, we risk infinite recursion when a transitioning
// (closed) overlay becomes the current overlay.
//
// NOTE: We make the assumption that any overlay that completes a transition
// will call into focusOverlay to kick the process back off. Currently:
// transitionend -> applyFocus -> focusOverlay.
if (current && !current.transitioning) {
current.applyFocus();
}
}
var backdrops = [];
function trackBackdrop(element) {
if (element.opened) {
backdrops.push(element);
} else {
var i = backdrops.indexOf(element);
if (i >= 0) {
backdrops.splice(i, 1);
}
}
}
function getBackdrops() {
return backdrops;
}
})();
</script>
</polymer-element>
<!--
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<link rel="import" href="//www.polymer-project.org/components/polymer/polymer.html">
<polymer-element name="core-overlay-layer">
<template>
<style>
:host {
position: fixed;
top: 0;
left: 0;
z-index: 1000;
display: none;
}
:host(.core-opened) {
display: block;
}
</style>
<content></content>
</template>
<script>
(function() {
Polymer('core-overlay-layer', {
publish: {
opened: false
},
openedChanged: function() {
this.classList.toggle('core-opened', this.opened);
},
/**
* Adds an element to the overlay layer
*/
addElement: function(element) {
if (!this.parentNode) {
document.querySelector('body').appendChild(this);
}
if (element.parentNode !== this) {
element.__contents = [];
var ip$ = element.querySelectorAll('content');
for (var i=0, l=ip$.length, n; (i<l) && (n = ip$[i]); i++) {
this.moveInsertedElements(n);
this.cacheDomLocation(n);
n.parentNode.removeChild(n);
element.__contents.push(n);
}
this.cacheDomLocation(element);
this.updateEventController(element);
var h = this.makeHost();
h.shadowRoot.appendChild(element);
element.__host = h;
}
},
makeHost: function() {
var h = document.createElement('overlay-host');
h.createShadowRoot();
this.appendChild(h);
return h;
},
moveInsertedElements: function(insertionPoint) {
var n$ = insertionPoint.getDistributedNodes();
var parent = insertionPoint.parentNode;
insertionPoint.__contents = [];
for (var i=0, l=n$.length, n; (i<l) && (n=n$[i]); i++) {
this.cacheDomLocation(n);
this.updateEventController(n);
insertionPoint.__contents.push(n);
parent.appendChild(n);
}
},
updateEventController: function(element) {
element.eventController = this.element.findController(element);
},
/**
* Removes an element from the overlay layer
*/
removeElement: function(element) {
element.eventController = null;
this.replaceElement(element);
var h = element.__host;
if (h) {
h.parentNode.removeChild(h);
}
},
replaceElement: function(element) {
if (element.__contents) {
for (var i=0, c$=element.__contents, c; (c=c$[i]); i++) {
this.replaceElement(c);
}
element.__contents = null;
}
if (element.__parentNode) {
var n = element.__nextElementSibling && element.__nextElementSibling
=== element.__parentNode ? element.__nextElementSibling : null;
element.__parentNode.insertBefore(element, n);
}
},
cacheDomLocation: function(element) {
element.__nextElementSibling = element.nextElementSibling;
element.__parentNode = element.parentNode;
}
});
})();
</script>
</polymer-element>
<!--
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<style shim-shadowdom>
/*******************************
Flex Layout
*******************************/
html /deep/ [layout][horizontal], html /deep/ [layout][vertical] {
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
html /deep/ [layout][horizontal][inline], html /deep/ [layout][vertical][inline] {
display: -ms-inline-flexbox;
display: -webkit-inline-flex;
display: inline-flex;
}
html /deep/ [layout][horizontal] {
-ms-flex-direction: row;
-webkit-flex-direction: row;
flex-direction: row;
}
html /deep/ [layout][horizontal][reverse] {
-ms-flex-direction: row-reverse;
-webkit-flex-direction: row-reverse;
flex-direction: row-reverse;
}
html /deep/ [layout][vertical] {
-ms-flex-direction: column;
-webkit-flex-direction: column;
flex-direction: column;
}
html /deep/ [layout][vertical][reverse] {
-ms-flex-direction: column-reverse;
-webkit-flex-direction: column-reverse;
flex-direction: column-reverse;
}
html /deep/ [layout][wrap] {
-ms-flex-wrap: wrap;
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
}
html /deep/ [layout][wrap-reverse] {
-ms-flex-wrap: wrap-reverse;
-webkit-flex-wrap: wrap-reverse;
flex-wrap: wrap-reverse;
}
html /deep/ [flex] {
-ms-flex: 1 1 0.000000001px;
-webkit-flex: 1;
flex: 1;
-webkit-flex-basis: 0.000000001px;
flex-basis: 0.000000001px;
}
html /deep/ [vertical][layout] > [flex][auto-vertical], html /deep/ [vertical][layout]::shadow [flex][auto-vertical] {
-ms-flex: 1 1 auto;
-webkit-flex-basis: auto;
flex-basis: auto;
}
html /deep/ [flex][auto] {
-ms-flex: 1 1 auto;
-webkit-flex-basis: auto;
flex-basis: auto;
}
html /deep/ [flex][none] {
-ms-flex: none;
-webkit-flex: none;
flex: none;
}
html /deep/ [flex][one] {
-ms-flex: 1;
-webkit-flex: 1;
flex: 1;
}
html /deep/ [flex][two] {
-ms-flex: 2;
-webkit-flex: 2;
flex: 2;
}
html /deep/ [flex][three] {
-ms-flex: 3;
-webkit-flex: 3;
flex: 3;
}
html /deep/ [flex][four] {
-ms-flex: 4;
-webkit-flex: 4;
flex: 4;
}
html /deep/ [flex][five] {
-ms-flex: 5;
-webkit-flex: 5;
flex: 5;
}
html /deep/ [flex][six] {
-ms-flex: 6;
-webkit-flex: 6;
flex: 6;
}
html /deep/ [flex][seven] {
-ms-flex: 7;
-webkit-flex: 7;
flex: 7;
}
html /deep/ [flex][eight] {
-ms-flex: 8;
-webkit-flex: 8;
flex: 8;
}
html /deep/ [flex][nine] {
-ms-flex: 9;
-webkit-flex: 9;
flex: 9;
}
html /deep/ [flex][ten] {
-ms-flex: 10;
-webkit-flex: 10;
flex: 10;
}
html /deep/ [flex][eleven] {
-ms-flex: 11;
-webkit-flex: 11;
flex: 11;
}
html /deep/ [flex][twelve] {
-ms-flex: 12;
-webkit-flex: 12;
flex: 12;
}
/* alignment in cross axis */
html /deep/ [layout][start] {
-ms-flex-align: start;
-webkit-align-items: flex-start;
align-items: flex-start;
}
html /deep/ [layout][center], html /deep/ [layout][center-center] {
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
}
html /deep/ [layout][end] {
-ms-flex-align: end;
-webkit-align-items: flex-end;
align-items: flex-end;
}
/* alignment in main axis */
html /deep/ [layout][start-justified] {
-ms-flex-pack: start;
-webkit-justify-content: flex-start;
justify-content: flex-start;
}
html /deep/ [layout][center-justified], html /deep/ [layout][center-center] {
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
}
html /deep/ [layout][end-justified] {
-ms-flex-pack: end;
-webkit-justify-content: flex-end;
justify-content: flex-end;
}
html /deep/ [layout][around-justified] {
-ms-flex-pack: distribute;
-webkit-justify-content: space-around;
justify-content: space-around;
}
html /deep/ [layout][justified] {
-ms-flex-pack: justify;
-webkit-justify-content: space-between;
justify-content: space-between;
}
/* self alignment */
html /deep/ [self-start] {
-ms-align-self: flex-start;
-webkit-align-self: flex-start;
align-self: flex-start;
}
html /deep/ [self-center] {
-ms-align-self: center;
-webkit-align-self: center;
align-self: center;
}
html /deep/ [self-end] {
-ms-align-self: flex-end;
-webkit-align-self: flex-end;
align-self: flex-end;
}
html /deep/ [self-stretch] {
-ms-align-self: stretch;
-webkit-align-self: stretch;
align-self: stretch;
}
/*******************************
Other Layout
*******************************/
html /deep/ [block] {
display: block;
}
/* ie support for hidden */
html /deep/ [hidden] {
display: none !important;
}
html /deep/ [relative] {
position: relative;
}
html /deep/ [fit] {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
body[fullbleed] {
margin: 0;
height: 100vh;
}
/*******************************
Other
*******************************/
html /deep/ [segment], html /deep/ segment {
display: block;
position: relative;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
margin: 1em 0.5em;
padding: 1em;
background-color: white;
-webkit-box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.1);
box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.1);
border-radius: 5px 5px 5px 5px;
}
</style>