Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(366)

Side by Side Diff: polymer_0.5.0/bower_components/paper-input/paper-input-decorator.html

Issue 786953007: npm_modules: Fork bower_components into Polymer 0.4.0 and 0.5.0 versions (Closed) Base URL: https://chromium.googlesource.com/infra/third_party/npm_modules.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 <!--
2 Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
3 This code may only be used under the BSD style license found at http://polymer.g ithub.io/LICENSE
4 The complete set of authors may be found at http://polymer.github.io/AUTHORS
5 The complete set of contributors may be found at http://polymer.github.io/CONTRI BUTORS
6 Code distributed by Google as part of the polymer project is also
7 subject to an additional IP rights grant found at http://polymer.github.io/PATEN TS
8 -->
9
10 <!--
11
12 Material Design: <a href="http://www.google.com/design/spec/components/text-fiel ds.html">Text fields</a>
13
14 `paper-input-decorator` adds Material Design input field styling and animations to an element.
15
16 Example:
17
18 <paper-input-decorator label="Your Name">
19 <input is="core-input">
20 </paper-input-decorator>
21
22 <paper-input-decorator floatingLabel label="Your address">
23 <textarea></textarea>
24 </paper-input-decorator>
25
26 Theming
27 -------
28
29 `paper-input-decorator` uses `core-style` for global theming. The following opti ons are available:
30
31 - `CoreStyle.g.paperInput.labelColor` - The inline label, floating label, error message and error icon color when the input does not have focus.
32 - `CoreStyle.g.paperInput.focusedColor` - The floating label and the underline c olor when the input has focus.
33 - `CoreStyle.g.paperInput.invalidColor` - The error message, the error icon, the floating label and the underline's color when the input is invalid and has focu s.
34
35 To add custom styling to only some elements, use these selectors:
36
37 paper-input-decorator /deep/ .label-text,
38 paper-input-decorator /deep/ .error {
39 /* inline label, floating label, error message and error icon color whe n the input is unfocused */
40 color: green;
41 }
42
43 paper-input-decorator /deep/ ::-webkit-input-placeholder {
44 /* platform specific rules for placeholder text */
45 color: green;
46 }
47 paper-input-decorator /deep/ ::-moz-placeholder {
48 color: green;
49 }
50 paper-input-decorator /deep/ :-ms-input-placeholder {
51 color: green;
52 }
53
54 paper-input-decorator /deep/ .unfocused-underline {
55 /* line color when the input is unfocused */
56 background-color: green;
57 }
58
59 paper-input-decorator[focused] /deep/ .floating-label .label-text {
60 /* floating label color when the input is focused */
61 color: orange;
62 }
63
64 paper-input-decorator /deep/ .focused-underline {
65 /* line color when the input is focused */
66 background-color: orange;
67 }
68
69 paper-input-decorator.invalid[focused] /deep/ .floated-label .label-text,
70 paper-input-decorator[focused] /deep/ .error {
71 /* floating label, error message nad error icon color when the input is invalid and focused */
72 color: salmon;
73 }
74
75 paper-input-decorator.invalid /deep/ .focused-underline {
76 /* line and color when the input is invalid and focused */
77 background-color: salmon;
78 }
79
80 Form submission
81 ---------------
82
83 You can use inputs decorated with this element in a `form` as usual.
84
85 Validation
86 ----------
87
88 Because you provide the `input` element to `paper-input-decorator`, you can use any validation library
89 or the <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Co nstraint_validation">HTML5 Constraints Validation API</a>
90 to implement validation. Set the `isInvalid` attribute when the input is validat ed, and provide an
91 error message in the `error` attribute.
92
93 Example:
94
95 <paper-input-decorator id="paper1" error="Value must start with a number!">
96 <input id="input1" is="core-input" pattern="^[0-9].*">
97 </paper-input-decorator>
98 <button onclick="validate()"></button>
99 <script>
100 function validate() {
101 var decorator = document.getElementById('paper1');
102 var input = document.getElementById('input1');
103 decorator.isInvalid = !input.validity.valid;
104 }
105 </script>
106
107 Example to validate as the user types:
108
109 <template is="auto-binding">
110 <paper-input-decorator id="paper2" error="Value must start with a number !" isInvalid="{{!$.input2.validity.valid}}">
111 <input id="input2" is="core-input" pattern="^[0-9].*">
112 </paper-input-decorator>
113 </template>
114
115 Accessibility
116 -------------
117
118 `paper-input-decorator` will automatically set the `aria-label` attribute on the nested input
119 to the value of `label`. Do not set the `placeholder` attribute on the nested in put, as it will
120 conflict with this element.
121
122 @group Paper Elements
123 @element paper-input-decorator
124 @homepage github.io
125 -->
126 <link href="../polymer/polymer.html" rel="import">
127 <link href="../core-icon/core-icon.html" rel="import">
128 <link href="../core-icons/core-icons.html" rel="import">
129 <link href="../core-input/core-input.html" rel="import">
130 <link href="../core-style/core-style.html" rel="import">
131
132 <core-style id="paper-input-decorator">
133
134 .label-text,
135 .error {
136 color: {{g.paperInput.labelColor}};
137 }
138
139 ::-webkit-input-placeholder {
140 color: {{g.paperInput.labelColor}};
141 }
142
143 ::-moz-placeholder {
144 color: {{g.paperInput.labelColor}};
145 }
146
147 :-ms-input-placeholder {
148 color: {{g.paperInput.labelColor}};
149 }
150
151 .unfocused-underline {
152 background-color: {{g.paperInput.labelColor}};
153 }
154
155 :host([focused]) .floated-label .label-text {
156 color: {{g.paperInput.focusedColor}};
157 }
158
159 .focused-underline {
160 background-color: {{g.paperInput.focusedColor}};
161 }
162
163 :host(.invalid) .floated-label .label-text,
164 .error {
165 color: {{g.paperInput.invalidColor}};
166 }
167
168 :host(.invalid) .unfocused-underline,
169 :host(.invalid) .focused-underline {
170 background-color: {{g.paperInput.invalidColor}};
171 }
172
173 </core-style>
174
175 <polymer-element name="paper-input-decorator" layout vertical
176 on-transitionEnd="{{transitionEndAction}}" on-webkitTransitionEnd="{{transitio nEndAction}}"
177 on-input="{{inputAction}}"
178 on-down="{{downAction}}">
179
180 <template>
181
182 <link href="paper-input-decorator.css" rel="stylesheet">
183 <core-style ref="paper-input-decorator"></core-style>
184
185 <div class="floated-label" aria-hidden="true" hidden?="{{!floatingLabel}}" i nvisible?="{{!floatingLabelVisible || labelAnimated}}">
186 <!-- needed for floating label animation measurement -->
187 <span id="floatedLabelText" class="label-text">{{label}}</span>
188 </div>
189
190 <div class="input-body" flex auto relative>
191
192 <div class="label" fit invisible aria-hidden="true">
193 <!-- needed for floating label animation measurement -->
194 <span id="labelText" class="label-text" invisible?="{{!_labelVisible}}" animated?="{{labelAnimated}}">{{label}}</span>
195 </div>
196
197 <content></content>
198
199 </div>
200
201 <div id="underline" class="underline" relative>
202 <div class="unfocused-underline" fit invisible?="{{disabled}}"></div>
203 <div id="focusedUnderline" class="focused-underline" fit invisible?="{{!fo cused}}" animated?="{{underlineAnimated}}"></div>
204 </div>
205
206 <div class="error" layout horizontal center hidden?="{{!isInvalid}}">
207 <div class="error-text" flex auto role="alert" aria-hidden="{{!isInvalid}} ">{{error}}</div>
208 <core-icon class="error-icon" icon="warning"></core-icon>
209 </div>
210
211 </template>
212
213 <script>
214
215 (function() {
216
217 var paperInput = CoreStyle.g.paperInput = CoreStyle.g.paperInput || {};
218
219 paperInput.labelColor = '#757575';
220 paperInput.focusedColor = '#4059a9';
221 paperInput.invalidColor = '#d34336';
222
223 Polymer({
224
225 publish: {
226
227 /**
228 * The label for this input. It normally appears as grey text inside
229 * the text input and disappears once the user enters text.
230 *
231 * @attribute label
232 * @type string
233 * @default ''
234 */
235 label: '',
236
237 /**
238 * If true, the label will "float" above the text input once the
239 * user enters text instead of disappearing.
240 *
241 * @attribute floatingLabel
242 * @type boolean
243 * @default false
244 */
245 floatingLabel: false,
246
247 /**
248 * Set to true to style the element as disabled.
249 *
250 * @attribute disabled
251 * @type boolean
252 * @default false
253 */
254 disabled: {value: false, reflect: true},
255
256 /**
257 * Use this property to override the automatic label visibility.
258 * If this property is set to `true` or `false`, the label visibility
259 * will respect this value instead of be based on whether there is
260 * a non-null value in the input.
261 *
262 * @attribute labelVisible
263 * @type boolean
264 * @default false
265 */
266 labelVisible: null,
267
268 /**
269 * Set this property to true to show the error message.
270 *
271 * @attribute isInvalid
272 * @type boolean
273 * @default false
274 */
275 isInvalid: false,
276
277 /**
278 * The message to display if the input value fails validation. If this
279 * is unset or the empty string, a default message is displayed dependin g
280 * on the type of validation error.
281 *
282 * @attribute error
283 * @type string
284 */
285 error: '',
286
287 focused: {value: false, reflect: true}
288
289 },
290
291 computed: {
292 floatingLabelVisible: 'floatingLabel && !_labelVisible',
293 _labelVisible: '(labelVisible === true || labelVisible === false) ? labe lVisible : _autoLabelVisible'
294 },
295
296 ready: function() {
297 // Delegate focus/blur events
298 Polymer.addEventListener(this, 'focus', this.focusAction.bind(this), tru e);
299 Polymer.addEventListener(this, 'blur', this.blurAction.bind(this), true) ;
300 },
301
302 attached: function() {
303 this.input = this.querySelector('input,textarea');
304
305 this.mo = new MutationObserver(function() {
306 this.input = this.querySelector('input,textarea');
307 }.bind(this));
308 this.mo.observe(this, {childList: true});
309 },
310
311 detached: function() {
312 this.mo.disconnect();
313 this.mo = null;
314 },
315
316 prepareLabelTransform: function() {
317 var toRect = this.$.floatedLabelText.getBoundingClientRect();
318 var fromRect = this.$.labelText.getBoundingClientRect();
319 if (toRect.width !== 0) {
320 var sy = toRect.height / fromRect.height;
321 this.$.labelText.cachedTransform =
322 'scale3d(' + (toRect.width / fromRect.width) + ',' + sy + ',1) ' +
323 'translate3d(0,' + (toRect.top - fromRect.top) / sy + 'px,0)';
324 }
325 },
326
327 animateFloatingLabel: function() {
328 if (!this.floatingLabel || this.labelAnimated) {
329 return false;
330 }
331
332 if (!this.$.labelText.cachedTransform) {
333 this.prepareLabelTransform();
334 }
335
336 // If there's still no cached transform, the input is invisible so don't
337 // do the animation.
338 if (!this.$.labelText.cachedTransform) {
339 return false;
340 }
341
342 this.labelAnimated = true;
343 // Handle interrupted animation
344 this.async(function() {
345 this.transitionEndAction();
346 }, null, 250);
347
348 if (this._labelVisible) {
349 // Handle if the label started out floating
350 if (!this.$.labelText.style.webkitTransform && !this.$.labelText.style .transform) {
351 this.$.labelText.style.webkitTransform = this.$.labelText.cachedTran sform;
352 this.$.labelText.style.transform = this.$.labelText.cachedTransform;
353 this.$.labelText.offsetTop;
354 }
355 this.$.labelText.style.webkitTransform = '';
356 this.$.labelText.style.transform = '';
357 } else {
358 this.$.labelText.style.webkitTransform = this.$.labelText.cachedTransf orm;
359 this.$.labelText.style.transform = this.$.labelText.cachedTransform;
360 this.input.placeholder = '';
361 }
362
363 return true;
364 },
365
366 _labelVisibleChanged: function(old) {
367 // do not do the animation on first render
368 if (old !== undefined) {
369 if (!this.animateFloatingLabel()) {
370 this.updateInputLabel(this.input, this.label);
371 }
372 }
373 },
374
375 labelVisibleChanged: function() {
376 if (this.labelVisible === 'true') {
377 this.labelVisible = true;
378 } else if (this.labelVisible === 'false') {
379 this.labelVisible = false;
380 }
381 },
382
383 labelChanged: function() {
384 if (this.input) {
385 this.updateInputLabel(this.input, this.label);
386 }
387 },
388
389 isInvalidChanged: function() {
390 this.classList.toggle('invalid', this.isInvalid);
391 },
392
393 focusedChanged: function() {
394 this.updateLabelVisibility(this.input && this.input.value);
395 },
396
397 inputChanged: function(old) {
398 if (this.input) {
399 this.updateLabelVisibility(this.input.value);
400 this.updateInputLabel(this.input, this.label);
401 }
402 if (old) {
403 this.updateInputLabel(old, '');
404 }
405 },
406
407 focusAction: function() {
408 this.focused = true;
409 },
410
411 blurAction: function(e) {
412 this.focused = false;
413 },
414
415 /**
416 * Updates the label visibility based on a value. This is handled automati cally
417 * if the user is typing, but if you imperatively set the input value you need
418 * to call this function.
419 *
420 * @method updateLabelVisibility
421 * @param {string} value
422 */
423 updateLabelVisibility: function(value) {
424 var v = (value !== null && value !== undefined) ? String(value) : value;
425 this._autoLabelVisible = (!this.focused && !v) || (!this.floatingLabel & & !v);
426 },
427
428 updateInputLabel: function(input, label) {
429 if (this._labelVisible) {
430 this.input.placeholder = this.label;
431 } else {
432 this.input.placeholder = '';
433 }
434 if (label) {
435 input.setAttribute('aria-label', label);
436 } else {
437 input.removeAttribute('aria-label');
438 }
439 },
440
441 inputAction: function(e) {
442 this.updateLabelVisibility(e.target.value);
443 },
444
445 downAction: function(e) {
446 if (this.disabled) {
447 return;
448 }
449
450 if (this.focused) {
451 return;
452 }
453
454 if (this.input) {
455 this.input.focus();
456 e.preventDefault();
457 }
458
459 // The underline spills from the tap location
460 var rect = this.$.underline.getBoundingClientRect();
461 var right = e.x - rect.left;
462 this.$.focusedUnderline.style.mozTransformOrigin = right + 'px';
463 this.$.focusedUnderline.style.webkitTransformOrigin = right + 'px ';
464 this.$.focusedUnderline.style.transformOriginX = right + 'px';
465
466 // Animations only run when the user interacts with the input
467 this.underlineAnimated = true;
468
469 // Handle interrupted animation
470 this.async(function() {
471 this.transitionEndAction();
472 }, null, 250);
473 },
474
475 transitionEndAction: function() {
476 this.underlineAnimated = false;
477 this.labelAnimated = false;
478 if (this._labelVisible) {
479 this.input.placeholder = this.label;
480 }
481 }
482
483 });
484
485 }());
486
487 </script>
488
489 </polymer-element>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698