aboutsummaryrefslogtreecommitdiff
path: root/catapult/third_party/polymer/components/paper-dropdown-menu/paper-dropdown-menu.html
diff options
context:
space:
mode:
Diffstat (limited to 'catapult/third_party/polymer/components/paper-dropdown-menu/paper-dropdown-menu.html')
-rw-r--r--catapult/third_party/polymer/components/paper-dropdown-menu/paper-dropdown-menu.html415
1 files changed, 415 insertions, 0 deletions
diff --git a/catapult/third_party/polymer/components/paper-dropdown-menu/paper-dropdown-menu.html b/catapult/third_party/polymer/components/paper-dropdown-menu/paper-dropdown-menu.html
new file mode 100644
index 00000000..98ebeccf
--- /dev/null
+++ b/catapult/third_party/polymer/components/paper-dropdown-menu/paper-dropdown-menu.html
@@ -0,0 +1,415 @@
+<!--
+@license
+Copyright (c) 2015 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="../polymer/polymer.html">
+<link rel="import" href="../iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
+<link rel="import" href="../iron-behaviors/iron-button-state.html">
+<link rel="import" href="../iron-behaviors/iron-control-state.html">
+<link rel="import" href="../iron-form-element-behavior/iron-form-element-behavior.html">
+<link rel="import" href="../iron-icon/iron-icon.html">
+<link rel="import" href="../iron-validatable-behavior/iron-validatable-behavior.html">
+<link rel="import" href="../paper-input/paper-input.html">
+<link rel="import" href="../paper-menu-button/paper-menu-button.html">
+<link rel="import" href="../paper-ripple/paper-ripple.html">
+<link rel="import" href="../paper-styles/default-theme.html">
+
+<link rel="import" href="paper-dropdown-menu-icons.html">
+<link rel="import" href="paper-dropdown-menu-shared-styles.html">
+
+<!--
+Material design: [Dropdown menus](https://www.google.com/design/spec/components/buttons.html#buttons-dropdown-buttons)
+
+`paper-dropdown-menu` is similar to a native browser select element.
+`paper-dropdown-menu` works with selectable content. The currently selected
+item is displayed in the control. If no item is selected, the `label` is
+displayed instead.
+
+Example:
+
+ <paper-dropdown-menu label="Your favourite pastry">
+ <paper-listbox class="dropdown-content">
+ <paper-item>Croissant</paper-item>
+ <paper-item>Donut</paper-item>
+ <paper-item>Financier</paper-item>
+ <paper-item>Madeleine</paper-item>
+ </paper-listbox>
+ </paper-dropdown-menu>
+
+This example renders a dropdown menu with 4 options.
+
+The child element with the class `dropdown-content` is used as the dropdown
+menu. This can be a [`paper-listbox`](paper-listbox), or any other or
+element that acts like an [`iron-selector`](iron-selector).
+
+Specifically, the menu child must fire an
+[`iron-select`](iron-selector#event-iron-select) event when one of its
+children is selected, and an [`iron-deselect`](iron-selector#event-iron-deselect)
+event when a child is deselected. The selected or deselected item must
+be passed as the event's `detail.item` property.
+
+Applications can listen for the `iron-select` and `iron-deselect` events
+to react when options are selected and deselected.
+
+### Styling
+
+The following custom properties and mixins are also available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-dropdown-menu` | A mixin that is applied to the element host | `{}`
+`--paper-dropdown-menu-disabled` | A mixin that is applied to the element host when disabled | `{}`
+`--paper-dropdown-menu-ripple` | A mixin that is applied to the internal ripple | `{}`
+`--paper-dropdown-menu-button` | A mixin that is applied to the internal menu button | `{}`
+`--paper-dropdown-menu-input` | A mixin that is applied to the internal paper input | `{}`
+`--paper-dropdown-menu-icon` | A mixin that is applied to the internal icon | `{}`
+
+You can also use any of the `paper-input-container` and `paper-menu-button`
+style mixins and custom properties to style the internal input and menu button
+respectively.
+
+@group Paper Elements
+@element paper-dropdown-menu
+@hero hero.svg
+@demo demo/index.html
+-->
+
+<dom-module id="paper-dropdown-menu">
+ <template>
+ <style include="paper-dropdown-menu-shared-styles"></style>
+
+ <!-- this div fulfills an a11y requirement for combobox, do not remove -->
+ <span role="button"></span>
+ <paper-menu-button
+ id="menuButton"
+ vertical-align="[[verticalAlign]]"
+ horizontal-align="[[horizontalAlign]]"
+ dynamic-align="[[dynamicAlign]]"
+ vertical-offset="[[_computeMenuVerticalOffset(noLabelFloat)]]"
+ disabled="[[disabled]]"
+ no-animations="[[noAnimations]]"
+ on-iron-select="_onIronSelect"
+ on-iron-deselect="_onIronDeselect"
+ opened="{{opened}}"
+ close-on-activate
+ allow-outside-scroll="[[allowOutsideScroll]]"
+ restore-focus-on-close="[[restoreFocusOnClose]]">
+ <div class="dropdown-trigger">
+ <paper-ripple></paper-ripple>
+ <!-- paper-input has type="text" for a11y, do not remove -->
+ <paper-input
+ type="text"
+ invalid="[[invalid]]"
+ readonly
+ disabled="[[disabled]]"
+ value="[[selectedItemLabel]]"
+ placeholder="[[placeholder]]"
+ error-message="[[errorMessage]]"
+ always-float-label="[[alwaysFloatLabel]]"
+ no-label-float="[[noLabelFloat]]"
+ label="[[label]]">
+ <iron-icon icon="paper-dropdown-menu:arrow-drop-down" suffix></iron-icon>
+ </paper-input>
+ </div>
+ <content id="content" select=".dropdown-content"></content>
+ </paper-menu-button>
+ </template>
+
+ <script>
+ (function() {
+ 'use strict';
+
+ Polymer({
+ is: 'paper-dropdown-menu',
+
+ behaviors: [
+ Polymer.IronButtonState,
+ Polymer.IronControlState,
+ Polymer.IronFormElementBehavior,
+ Polymer.IronValidatableBehavior
+ ],
+
+ properties: {
+ /**
+ * The derived "label" of the currently selected item. This value
+ * is the `label` property on the selected item if set, or else the
+ * trimmed text content of the selected item.
+ */
+ selectedItemLabel: {
+ type: String,
+ notify: true,
+ readOnly: true
+ },
+
+ /**
+ * The last selected item. An item is selected if the dropdown menu has
+ * a child with class `dropdown-content`, and that child triggers an
+ * `iron-select` event with the selected `item` in the `detail`.
+ *
+ * @type {?Object}
+ */
+ selectedItem: {
+ type: Object,
+ notify: true,
+ readOnly: true
+ },
+
+ /**
+ * The value for this element that will be used when submitting in
+ * a form. It is read only, and will always have the same value
+ * as `selectedItemLabel`.
+ */
+ value: {
+ type: String,
+ notify: true,
+ readOnly: true
+ },
+
+ /**
+ * The label for the dropdown.
+ */
+ label: {
+ type: String
+ },
+
+ /**
+ * The placeholder for the dropdown.
+ */
+ placeholder: {
+ type: String
+ },
+
+ /**
+ * The error message to display when invalid.
+ */
+ errorMessage: {
+ type: String
+ },
+
+ /**
+ * True if the dropdown is open. Otherwise, false.
+ */
+ opened: {
+ type: Boolean,
+ notify: true,
+ value: false,
+ observer: '_openedChanged'
+ },
+
+ /**
+ * By default, the dropdown will constrain scrolling on the page
+ * to itself when opened.
+ * Set to true in order to prevent scroll from being constrained
+ * to the dropdown when it opens.
+ */
+ allowOutsideScroll: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to disable the floating label. Bind this to the
+ * `<paper-input-container>`'s `noLabelFloat` property.
+ */
+ noLabelFloat: {
+ type: Boolean,
+ value: false,
+ reflectToAttribute: true
+ },
+
+ /**
+ * Set to true to always float the label. Bind this to the
+ * `<paper-input-container>`'s `alwaysFloatLabel` property.
+ */
+ alwaysFloatLabel: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to disable animations when opening and closing the
+ * dropdown.
+ */
+ noAnimations: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * The orientation against which to align the menu dropdown
+ * horizontally relative to the dropdown trigger.
+ */
+ horizontalAlign: {
+ type: String,
+ value: 'right'
+ },
+
+ /**
+ * The orientation against which to align the menu dropdown
+ * vertically relative to the dropdown trigger.
+ */
+ verticalAlign: {
+ type: String,
+ value: 'top'
+ },
+
+ /**
+ * If true, the `horizontalAlign` and `verticalAlign` properties will
+ * be considered preferences instead of strict requirements when
+ * positioning the dropdown and may be changed if doing so reduces
+ * the area of the dropdown falling outside of `fitInto`.
+ */
+ dynamicAlign: {
+ type: Boolean
+ },
+
+ /**
+ * Whether focus should be restored to the dropdown when the menu closes.
+ */
+ restoreFocusOnClose: {
+ type: Boolean,
+ value: true
+ },
+ },
+
+ listeners: {
+ 'tap': '_onTap'
+ },
+
+ keyBindings: {
+ 'up down': 'open',
+ 'esc': 'close'
+ },
+
+ hostAttributes: {
+ role: 'combobox',
+ 'aria-autocomplete': 'none',
+ 'aria-haspopup': 'true'
+ },
+
+ observers: [
+ '_selectedItemChanged(selectedItem)'
+ ],
+
+ attached: function() {
+ // NOTE(cdata): Due to timing, a preselected value in a `IronSelectable`
+ // child will cause an `iron-select` event to fire while the element is
+ // still in a `DocumentFragment`. This has the effect of causing
+ // handlers not to fire. So, we double check this value on attached:
+ var contentElement = this.contentElement;
+ if (contentElement && contentElement.selectedItem) {
+ this._setSelectedItem(contentElement.selectedItem);
+ }
+ },
+
+ /**
+ * The content element that is contained by the dropdown menu, if any.
+ */
+ get contentElement() {
+ return Polymer.dom(this.$.content).getDistributedNodes()[0];
+ },
+
+ /**
+ * Show the dropdown content.
+ */
+ open: function() {
+ this.$.menuButton.open();
+ },
+
+ /**
+ * Hide the dropdown content.
+ */
+ close: function() {
+ this.$.menuButton.close();
+ },
+
+ /**
+ * A handler that is called when `iron-select` is fired.
+ *
+ * @param {CustomEvent} event An `iron-select` event.
+ */
+ _onIronSelect: function(event) {
+ this._setSelectedItem(event.detail.item);
+ },
+
+ /**
+ * A handler that is called when `iron-deselect` is fired.
+ *
+ * @param {CustomEvent} event An `iron-deselect` event.
+ */
+ _onIronDeselect: function(event) {
+ this._setSelectedItem(null);
+ },
+
+ /**
+ * A handler that is called when the dropdown is tapped.
+ *
+ * @param {CustomEvent} event A tap event.
+ */
+ _onTap: function(event) {
+ if (Polymer.Gestures.findOriginalTarget(event) === this) {
+ this.open();
+ }
+ },
+
+ /**
+ * Compute the label for the dropdown given a selected item.
+ *
+ * @param {Element} selectedItem A selected Element item, with an
+ * optional `label` property.
+ */
+ _selectedItemChanged: function(selectedItem) {
+ var value = '';
+ if (!selectedItem) {
+ value = '';
+ } else {
+ value = selectedItem.label || selectedItem.getAttribute('label') || selectedItem.textContent.trim();
+ }
+
+ this._setValue(value);
+ this._setSelectedItemLabel(value);
+ },
+
+ /**
+ * Compute the vertical offset of the menu based on the value of
+ * `noLabelFloat`.
+ *
+ * @param {boolean} noLabelFloat True if the label should not float
+ * above the input, otherwise false.
+ */
+ _computeMenuVerticalOffset: function(noLabelFloat) {
+ // NOTE(cdata): These numbers are somewhat magical because they are
+ // derived from the metrics of elements internal to `paper-input`'s
+ // template. The metrics will change depending on whether or not the
+ // input has a floating label.
+ return noLabelFloat ? -4 : 8;
+ },
+
+ /**
+ * Returns false if the element is required and does not have a selection,
+ * and true otherwise.
+ * @param {*=} _value Ignored.
+ * @return {boolean} true if `required` is false, or if `required` is true
+ * and the element has a valid selection.
+ */
+ _getValidity: function(_value) {
+ return this.disabled || !this.required || (this.required && !!this.value);
+ },
+
+ _openedChanged: function() {
+ var openState = this.opened ? 'true' : 'false';
+ var e = this.contentElement;
+ if (e) {
+ e.setAttribute('aria-expanded', openState);
+ }
+ }
+ });
+ })();
+ </script>
+</dom-module>