5 var paperInput
= CoreStyle
.g
.paperInput
= CoreStyle
.g
.paperInput
|| {};
6 paperInput
.focusedColor
= '#4059a9';
7 paperInput
.invalidColor
= '#d34336';
9 Polymer('paper-input', {
12 * The label for this input. It normally appears as grey text inside
13 * the text input and disappears once the user enters text.
22 * If true, the label will "float" above the text input once the
23 * user enters text instead of disappearing.
25 * @attribute floatingLabel
32 * (multiline only) If set to a non-zero value, the height of this
33 * text input will grow with the value changes until it is maxRows
34 * rows tall. If the maximum size does not fit the value, the text
35 * input will scroll internally.
44 * The message to display if the input value fails validation. If this
45 * is unset or the empty string, a default message is displayed depending
46 * on the type of validation error.
56 attached: function() {
59 window
.requestAnimationFrame(function() {
60 this.$.underlineContainer
.classList
.add('animating');
65 resizeInput: function() {
66 var height
= this.$.inputClone
.getBoundingClientRect().height
;
67 var bounded
= this.maxRows
> 0 || this.rows
> 0;
69 var minHeight
= this.$.minInputHeight
.getBoundingClientRect().height
;
70 var maxHeight
= this.$.maxInputHeight
.getBoundingClientRect().height
;
71 height
= Math
.max(minHeight
, Math
.min(height
, maxHeight
));
73 this.$.inputContainer
.style
.height
= height
+ 'px';
74 this.$.underlineContainer
.style
.top
= height
+ 'px';
77 prepareLabelTransform: function() {
78 var toRect
= this.$.floatedLabelSpan
.getBoundingClientRect();
79 var fromRect
= this.$.labelSpan
.getBoundingClientRect();
80 if (toRect
.width
!== 0) {
81 this.$.label
.cachedTransform
= 'scale(' + (toRect
.width
/ fromRect
.width
) + ') ' +
82 'translateY(' + (toRect
.bottom
- fromRect
.bottom
) + 'px)';
86 toggleLabel: function(force
) {
87 var v
= force
!== undefined ? force
: this.inputValue
;
89 if (!this.floatingLabel
) {
90 this.$.label
.classList
.toggle('hidden', v
);
93 if (this.floatingLabel
&& !this.focused
) {
94 this.$.label
.classList
.toggle('hidden', v
);
95 this.$.floatedLabel
.classList
.toggle('hidden', !v
);
99 rowsChanged: function() {
100 if (this.multiline
&& !isNaN(parseInt(this.rows
))) {
101 this.$.minInputHeight
.innerHTML
= '';
102 for (var i
= 0; i
< this.rows
; i
++) {
103 this.$.minInputHeight
.appendChild(document
.createElement('br'));
109 maxRowsChanged: function() {
110 if (this.multiline
&& !isNaN(parseInt(this.maxRows
))) {
111 this.$.maxInputHeight
.innerHTML
= '';
112 for (var i
= 0; i
< this.maxRows
; i
++) {
113 this.$.maxInputHeight
.appendChild(document
.createElement('br'));
119 inputValueChanged: function() {
122 if (this.multiline
) {
123 var escaped
= this.inputValue
.replace(/\n/gm, '<br>');
124 if (!escaped
|| escaped
.lastIndexOf('<br>') === escaped
.length
- 4) {
127 this.$.inputCloneSpan
.innerHTML
= escaped
;
134 labelChanged: function() {
135 if (this.floatingLabel
&& this.$.floatedLabel
&& this.$.label
) {
136 // If the element is created programmatically, labelChanged is called before
137 // binding. Run the measuring code in async so the DOM is ready.
138 this.async(function() {
139 this.prepareLabelTransform();
144 placeholderChanged: function() {
145 this.label
= this.placeholder
;
148 inputFocusAction: function() {
150 if (this.floatingLabel
) {
151 this.$.floatedLabel
.classList
.remove('hidden');
152 this.$.floatedLabel
.classList
.add('focused');
153 this.$.floatedLabel
.classList
.add('focusedColor');
155 this.$.label
.classList
.add('hidden');
156 this.$.underlineHighlight
.classList
.add('focused');
157 this.$.caret
.classList
.add('focused');
159 this.super(arguments
);
164 shouldFloatLabel: function() {
165 // if type = number, the input value is the empty string until a valid number
166 // is entered so we must do some hacks here
167 return this.inputValue
|| (this.type
=== 'number' && !this.validity
.valid
);
170 inputBlurAction: function() {
171 this.super(arguments
);
173 this.$.underlineHighlight
.classList
.remove('focused');
174 this.$.caret
.classList
.remove('focused');
176 if (this.floatingLabel
) {
177 this.$.floatedLabel
.classList
.remove('focused');
178 this.$.floatedLabel
.classList
.remove('focusedColor');
179 if (!this.shouldFloatLabel()) {
180 this.$.floatedLabel
.classList
.add('hidden');
184 // type = number hack. see core-input for more info
185 if (!this.shouldFloatLabel()) {
186 this.$.label
.classList
.remove('hidden');
187 this.$.label
.classList
.add('animating');
188 this.async(function() {
189 this.$.label
.style
.webkitTransform
= 'none';
190 this.$.label
.style
.transform
= 'none';
194 this.focused
= false;
197 downAction: function(e
) {
207 var rect
= this.$.underline
.getBoundingClientRect();
208 var right
= e
.x
- rect
.left
;
209 this.$.underlineHighlight
.style
.webkitTransformOriginX
= right
+ 'px';
210 this.$.underlineHighlight
.style
.transformOriginX
= right
+ 'px';
211 this.$.underlineHighlight
.classList
.remove('focused');
212 this.underlineAsync
= this.async(function() {
213 this.$.underlineHighlight
.classList
.add('pressed');
216 // No caret animation if there is text in the input.
217 if (!this.inputValue
) {
218 this.$.caret
.classList
.remove('focused');
222 upAction: function(e
) {
231 // if a touchevent caused the up, the synthentic mouseevents will blur
232 // the input, make sure to prevent those from being generated.
233 if (e
._source
=== 'touch') {
237 if (this.underlineAsync
) {
238 clearTimeout(this.underlineAsync
);
239 this.underlineAsync
= null;
242 // Focus the input here to bring up the virtual keyboard.
243 this.$.input
.focus();
244 this.pressed
= false;
245 this.animating
= true;
247 this.$.underlineHighlight
.classList
.remove('pressed');
248 this.$.underlineHighlight
.classList
.add('animating');
249 this.async(function() {
250 this.$.underlineHighlight
.classList
.add('focused');
253 // No caret animation if there is text in the input.
254 if (!this.inputValue
) {
255 this.$.caret
.classList
.add('animating');
256 this.async(function() {
257 this.$.caret
.classList
.add('focused');
261 if (this.floatingLabel
) {
262 this.$.label
.classList
.add('focusedColor');
263 this.$.label
.classList
.add('animating');
264 if (!this.$.label
.cachedTransform
) {
265 this.prepareLabelTransform();
267 this.$.label
.style
.webkitTransform
= this.$.label
.cachedTransform
;
268 this.$.label
.style
.transform
= this.$.label
.cachedTransform
;
272 keydownAction: function() {
275 // more type = number hacks. see core-input for more info
276 if (this.type
=== 'number') {
277 this.async(function() {
278 if (!this.inputValue
) {
279 this.toggleLabel(!this.validity
.valid
);
285 keypressAction: function() {
286 if (this.animating
) {
287 this.transitionEndAction();
291 transitionEndAction: function(e
) {
292 this.animating
= false;
299 if (this.floatingLabel
|| this.inputValue
) {
300 this.$.label
.classList
.add('hidden');
303 if (this.floatingLabel
) {
304 this.$.label
.classList
.remove('focusedColor');
305 this.$.label
.classList
.remove('animating');
306 this.$.floatedLabel
.classList
.remove('hidden');
307 this.$.floatedLabel
.classList
.add('focused');
308 this.$.floatedLabel
.classList
.add('focusedColor');
311 this.async(function() {
312 this.$.underlineHighlight
.classList
.remove('animating');
313 this.$.caret
.classList
.remove('animating');
318 this.$.label
.classList
.remove('animating');