<!-- 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 --> <!-- /** * @group Paper Elements * * paper-focusable is a base class for paper elements that can be focused. * * @element paper-focusable * @status beta * @homepage github.io */ --> <link href="../polymer/polymer.html" rel="import"> <polymer-element name="paper-focusable" attributes="active focused disabled isToggle" tabindex="0" on-down="{{downAction}}" on-up="{{upAction}}" on-focus="{{focusAction}}" on-blur="{{blurAction}}" on-contextmenu="{{contextMenuAction}}"> <template> <style> :host([disabled]) { pointer-events: none; } </style> <content></content> </template> <script> Polymer('paper-focusable', { publish: { /** * If true, the button is currently active either because the * user is holding down the button, or the button is a toggle * and is currently in the active state. * * @attribute active * @type boolean * @default false */ active: {value: false, reflect: true}, /** * If true, the element currently has focus due to keyboard * navigation. * * @attribute focused * @type boolean * @default false */ focused: {value: false, reflect: true}, /** * If true, the user is currently holding down the button. * * @attribute pressed * @type boolean * @default false */ pressed: {value: false, reflect: true}, /** * If true, the user cannot interact with this element. * * @attribute disabled * @type boolean * @default false */ disabled: {value: false, reflect: true}, /** * If true, the button toggles the active state with each tap. * Otherwise, the button becomes active when the user is holding * it down. * * @attribute isToggle * @type boolean * @default false */ isToggle: {value: false, reflect: false} }, disabledChanged: function() { if (this.disabled) { this.removeAttribute('tabindex'); } else { this.setAttribute('tabindex', 0); } }, downAction: function() { this.pressed = true; this.focused = false; if (this.isToggle) { this.active = !this.active; } else { this.active = true; } }, // Pulling up the context menu for an item should focus it; but we need to // be careful about how we deal with down/up events surrounding context // menus. The up event typically does not fire until the context menu // closes: so we focus immediately. // // This fires _after_ downAction. contextMenuAction: function(e) { // Note that upAction may fire _again_ on the actual up event. this.upAction(e); this.focusAction(); }, upAction: function() { this.pressed = false; if (!this.isToggle) { this.active = false; } }, focusAction: function() { if (!this.pressed) { // Only render the "focused" state if the element gains focus due to // keyboard navigation. this.focused = true; } }, blurAction: function() { this.focused = false; } }); </script> </polymer-element>