4 * @demo demo/index.html
5 * @polymerBehavior Polymer.IronButtonState
7 Polymer
.IronButtonStateImpl
= {
12 * If true, the user is currently holding down the button.
18 reflectToAttribute
: true,
19 observer
: '_pressedChanged'
23 * If true, the button toggles the active state with each tap or press
29 reflectToAttribute
: true
33 * If true, the button is a toggle and is currently in the active state.
39 reflectToAttribute
: true,
40 observer
: '_activeChanged'
44 * True if the element is currently being pressed by a "pointer," which
45 * is loosely defined as mouse or touch input (but specifically excluding
55 * True if the input device that caused the element to receive focus
58 receivedFocusFromKeyboard
: {
71 '_detectKeyboardFocus(focused)'
75 'enter:keydown': '_asyncClick',
76 'space:keydown': '_spaceKeyDownHandler',
77 'space:keyup': '_spaceKeyUpHandler',
80 _mouseEventRe
: /^mouse/,
82 _tapHandler: function() {
84 // a tap is needed to toggle the active state
85 this._userActivate(!this.active
);
91 _detectKeyboardFocus: function(focused
) {
92 this._setReceivedFocusFromKeyboard(!this.pointerDown
&& focused
);
95 // to emulate native checkbox, (de-)activations from a user interaction fire
97 _userActivate: function(active
) {
102 _eventSourceIsPrimaryInput: function(event
) {
103 event
= event
.detail
.sourceEvent
|| event
;
105 // Always true for non-mouse events....
106 if (!this._mouseEventRe
.test(event
.type
)) {
110 // http://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons
111 if ('buttons' in event
) {
112 return event
.buttons
=== 1;
115 // http://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/which
116 if (typeof event
.which
=== 'number') {
117 return event
.which
< 2;
120 // http://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button
121 return event
.button
< 1;
124 _downHandler: function(event
) {
125 if (!this._eventSourceIsPrimaryInput(event
)) {
129 this._setPointerDown(true);
130 this._setPressed(true);
131 this._setReceivedFocusFromKeyboard(false);
134 _upHandler: function() {
135 this._setPointerDown(false);
136 this._setPressed(false);
139 _spaceKeyDownHandler: function(event
) {
140 var keyboardEvent
= event
.detail
.keyboardEvent
;
141 keyboardEvent
.preventDefault();
142 keyboardEvent
.stopImmediatePropagation();
143 this._setPressed(true);
146 _spaceKeyUpHandler: function() {
150 this._setPressed(false);
153 // trigger click asynchronously, the asynchrony is useful to allow one
154 // event handler to unwind before triggering another event
155 _asyncClick: function() {
156 this.async(function() {
161 // any of these changes are considered a change to button state
163 _pressedChanged: function(pressed
) {
164 this._changedButtonState();
167 _activeChanged: function(active
) {
169 this.setAttribute('aria-pressed', active
? 'true' : 'false');
171 this.removeAttribute('aria-pressed');
173 this._changedButtonState();
176 _controlStateChanged: function() {
178 this._setPressed(false);
180 this._changedButtonState();
184 // provide hook for follow-on behaviors to react to button-state
186 _changedButtonState: function() {
187 if (this._buttonStateChanged
) {
188 this._buttonStateChanged(); // abstract
194 /** @polymerBehavior */
195 Polymer
.IronButtonState
= [
196 Polymer
.IronA11yKeysBehavior
,
197 Polymer
.IronButtonStateImpl