OLD | NEW |
1 <!-- | 1 <!-- |
2 @license | 2 @license |
3 Copyright (c) 2015 The Polymer Project Authors. All rights reserved. | 3 Copyright (c) 2015 The Polymer Project Authors. All rights reserved. |
4 This code may only be used under the BSD style license found at http://polymer.g
ithub.io/LICENSE.txt | 4 This code may only be used under the BSD style license found at http://polymer.g
ithub.io/LICENSE.txt |
5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt | 5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt |
6 The complete set of contributors may be found at http://polymer.github.io/CONTRI
BUTORS.txt | 6 The complete set of contributors may be found at http://polymer.github.io/CONTRI
BUTORS.txt |
7 Code distributed by Google as part of the polymer project is also | 7 Code distributed by Google as part of the polymer project is also |
8 subject to an additional IP rights grant found at http://polymer.github.io/PATEN
TS.txt | 8 subject to an additional IP rights grant found at http://polymer.github.io/PATEN
TS.txt |
9 --> | 9 --> |
10 | 10 |
11 <link rel="import" href="../polymer/polymer.html"> | 11 <link rel="import" href="../polymer/polymer.html"> |
12 <link rel="import" href="../paper-styles/paper-styles.html"> | 12 <link rel="import" href="../paper-styles/paper-styles.html"> |
13 | 13 |
14 <style is="x-style"> | |
15 | |
16 * { | |
17 | |
18 --paper-input-container-font: var(--paper-font-subhead); | |
19 --paper-input-container-floating-label-font: var(--paper-font-caption); | |
20 --paper-input-container-add-on-font: var(--paper-font-caption); | |
21 | |
22 --paper-input-container-focus-color: var(--default-primary-color); | |
23 --paper-input-container-color: var(--secondary-text-color); | |
24 --paper-input-container-invalid-color: var(--google-red-500); | |
25 --paper-input-container-input-color: var(--primary-text-color); | |
26 | |
27 } | |
28 | |
29 </style> | |
30 | |
31 <!-- | 14 <!-- |
32 `<paper-input-container>` wraps an `<input>` and `<label>` element, decorating | 15 `<paper-input-container>` is a container for a `<label>`, an `<input is="iron-in
put">` or |
33 them following the [Material Design spec](http://www.google.com/design/spec/comp
onents/text-fields.html#text-fields-single-line-text-field) | 16 `<iron-autogrow-textarea>` and optional add-on elements such as an error message
or character |
| 17 counter, used to implement Material Design text fields. |
34 | 18 |
35 For example: | 19 For example: |
36 | 20 |
37 <paper-input-container> | 21 <paper-input-container> |
38 <label>email address</label> | 22 <label>Your name</label> |
39 <input type="email"> | 23 <input is="iron-input"> |
40 </paper-input-container> | 24 </paper-input-container> |
41 | 25 |
| 26 ### Listening for input changes |
| 27 |
| 28 By default, it listens for changes on the `bind-value` attribute on its children
nodes and perform |
| 29 tasks such as auto-validating and label styling when the `bind-value` changes. Y
ou can configure |
| 30 the attribute it listens to with the `attr-for-value` attribute. |
| 31 |
| 32 ### Using a custom input element |
| 33 |
| 34 You can use a custom input element in a `<paper-input-container>`, for example t
o implement a |
| 35 compound input field like a social security number input. The custom input eleme
nt should have the |
| 36 `paper-input-input` class, have a `notify:true` value property and optionally im
plements |
| 37 `Polymer.IronValidatableBehavior` if it is validatble. |
| 38 |
| 39 <paper-input-container attr-for-value="ssn-value"> |
| 40 <label>Social security number</label> |
| 41 <ssn-input class="paper-input-input"></ssn-input> |
| 42 </paper-input-container> |
| 43 |
| 44 ### Validation |
| 45 |
| 46 If the `auto-validate` attribute is set, the input container will validate the i
nput and update |
| 47 the container styling when the input value changes. |
| 48 |
| 49 ### Add-ons |
| 50 |
| 51 Add-ons are child elements of a `<paper-input-container>` with the `add-on` attr
ibute and |
| 52 implements the `Polymer.PaperInputAddonBehavior` behavior. They are notified whe
n the input value |
| 53 or validity changes, and may implement functionality such as error messages or c
haracter counters. |
| 54 They appear at the bottom of the input. |
| 55 |
| 56 ### Styling |
| 57 |
| 58 The following custom properties and mixins are available for styling: |
| 59 |
| 60 Custom property | Description | Default |
| 61 ----------------|-------------|---------- |
| 62 `--paper-input-container-color` | Label and underline color when the input is no
t focused | `--secondary-text-color` |
| 63 `--paper-input-container-focus-color` | Label and underline color when the input
is focused | `--default-primary-color` |
| 64 `--paper-input-container-invalid-color` | Label and underline color when the inp
ut is focused | `--google-red-500` |
| 65 `--paper-input-container-input-color` | Input foreground color | `--primary-text
-color` |
| 66 `--paper-input-container` | Mixin applied to the container | `{}` |
| 67 `--paper-input-container-label` | Mixin applied to the label | `{}` |
| 68 `--paper-input-container-input` | Mixin applied to the input | `{}` |
| 69 |
| 70 This element is `display:block` by default, but you can set the `inline` attribu
te to make it |
| 71 `display:inline-block`. |
42 --> | 72 --> |
43 <dom-module id="paper-input-container"> | 73 <dom-module id="paper-input-container"> |
44 | 74 |
45 <style> | 75 <style> |
46 | 76 |
47 :host { | 77 :host { |
48 display: block; | 78 display: block; |
49 padding: 8px 0; | 79 padding: 8px 0; |
50 | 80 |
51 --mixin(--paper-input-container); | 81 @apply(--paper-input-container); |
| 82 } |
| 83 |
| 84 :host[inline] { |
| 85 display: inline-block; |
52 } | 86 } |
53 | 87 |
54 :host([disabled]) { | 88 :host([disabled]) { |
55 pointer-events: none; | 89 pointer-events: none; |
56 opacity: 0.33; | 90 opacity: 0.33; |
57 } | 91 } |
58 | 92 |
59 .floated-label-placeholder { | 93 .floated-label-placeholder { |
60 mixin(--paper-input-container-label-font); | 94 @apply(--paper-font-caption); |
| 95 } |
| 96 |
| 97 .underline { |
| 98 position: relative; |
61 } | 99 } |
62 | 100 |
63 .focused-line { | 101 .focused-line { |
64 height: 2px; | 102 height: 2px; |
65 | 103 |
66 -webkit-transform-origin: center center; | 104 -webkit-transform-origin: center center; |
67 transform-origin: center center; | 105 transform-origin: center center; |
68 -webkit-transform: scale3d(0,1,1); | 106 -webkit-transform: scale3d(0,1,1); |
69 transform: scale3d(0,1,1); | 107 transform: scale3d(0,1,1); |
70 | 108 |
71 background: var(--paper-input-container-focus-color); | 109 background: var(--paper-input-container-focus-color, --default-primary-col
or); |
72 } | 110 } |
73 | 111 |
74 .is-highlighted .focused-line { | 112 .is-highlighted .focused-line { |
75 -webkit-transform: none; | 113 -webkit-transform: none; |
76 transform: none; | 114 transform: none; |
77 -webkit-transition: -webkit-transform 0.25s; | 115 -webkit-transition: -webkit-transform 0.25s; |
78 transition: transform 0.25s; | 116 transition: transform 0.25s; |
79 | 117 |
80 mixin(--paper-transition-easing); | 118 @apply(--paper-transition-easing); |
81 } | 119 } |
82 | 120 |
83 .is-invalid .focused-line { | 121 .is-invalid .focused-line { |
84 background: var(--paper-input-container-invalid-color); | 122 background: var(--paper-input-container-invalid-color, --google-red-500); |
85 | 123 |
86 -webkit-transform: none; | 124 -webkit-transform: none; |
87 transform: none; | 125 transform: none; |
88 -webkit-transition: -webkit-transform 0.25s; | 126 -webkit-transition: -webkit-transform 0.25s; |
89 transition: transform 0.25s; | 127 transition: transform 0.25s; |
90 | 128 |
91 mixin(--paper-transition-easing); | 129 @apply(--paper-transition-easing); |
92 } | 130 } |
93 | 131 |
94 .unfocused-line { | 132 .unfocused-line { |
95 height: 1px; | 133 height: 1px; |
96 background: var(--paper-input-container-color); | 134 background: var(--paper-input-container-color, --secondary-text-color); |
97 } | 135 } |
98 | 136 |
99 :host([disabled]) .unfocused-line { | 137 :host([disabled]) .unfocused-line { |
100 border-bottom: 1px dashed; | 138 border-bottom: 1px dashed; |
101 border-color: var(--paper-input-container-color); | 139 border-color: var(--paper-input-container-color, --secondary-text-color); |
102 background: transparent; | 140 background: transparent; |
103 } | 141 } |
104 | 142 |
| 143 .input-content { |
| 144 position: relative; |
| 145 } |
| 146 |
105 .input-content ::content label, | 147 .input-content ::content label, |
106 .input-content ::content .paper-input-label { | 148 .input-content ::content .paper-input-label { |
107 position: absolute; | 149 position: absolute; |
108 top: 0; | 150 top: 0; |
109 right: 0; | 151 right: 0; |
110 left: 0; | 152 left: 0; |
111 font: inherit; | 153 font: inherit; |
112 color: var(--paper-input-container-color); | 154 color: var(--paper-input-container-color, --secondary-text-color); |
113 | 155 |
114 mixin(--paper-input-container-font); | 156 @apply(--paper-font-subhead); |
115 | 157 @apply(--paper-input-container-label); |
116 mixin(--paper-input-container-label); | |
117 } | 158 } |
118 | 159 |
119 .input-content.label-is-floating ::content label, | 160 .input-content.label-is-floating ::content label, |
120 .input-content.label-is-floating ::content .paper-input-label { | 161 .input-content.label-is-floating ::content .paper-input-label { |
121 -webkit-transform: translate3d(0, -75%, 0) scale(0.75); | 162 -webkit-transform: translate3d(0, -75%, 0) scale(0.75); |
122 transform: translate3d(0, -75%, 0) scale(0.75); | 163 transform: translate3d(0, -75%, 0) scale(0.75); |
123 -webkit-transform-origin: left top; | 164 -webkit-transform-origin: left top; |
124 transform-origin: left top; | 165 transform-origin: left top; |
125 -webkit-transition: -webkit-transform 0.25s; | 166 -webkit-transition: -webkit-transform 0.25s; |
126 transition: transform 0.25s; | 167 transition: transform 0.25s; |
127 | 168 |
128 mixin(--paper-transition-easing); | 169 @apply(--paper-transition-easing); |
129 } | 170 } |
130 | 171 |
131 .input-content.label-is-highlighted ::content label, | 172 .input-content.label-is-highlighted ::content label, |
132 .input-content.label-is-highlighted ::content .paper-input-label { | 173 .input-content.label-is-highlighted ::content .paper-input-label { |
133 color: var(--paper-input-container-focus-color); | 174 color: var(--paper-input-container-focus-color, --default-primary-color); |
134 } | 175 } |
135 | 176 |
136 .input-content.is-invalid ::content label, | 177 .input-content.is-invalid ::content label, |
137 .input-content.is-invalid ::content .paper-input-label { | 178 .input-content.is-invalid ::content .paper-input-label { |
138 color: var(--paper-input-container-invalid-color); | 179 color: var(--paper-input-container-invalid-color, --google-red-500); |
139 } | 180 } |
140 | 181 |
141 .input-content.label-is-hidden ::content label, | 182 .input-content.label-is-hidden ::content label, |
142 .input-content.label-is-hidden ::content .paper-input-label { | 183 .input-content.label-is-hidden ::content .paper-input-label { |
143 visibility: hidden; | 184 visibility: hidden; |
144 } | 185 } |
145 | 186 |
146 .input-content ::content input, | 187 .input-content ::content input, |
147 .input-content ::content textarea, | 188 .input-content ::content textarea, |
| 189 .input-content ::content iron-autogrow-textarea, |
148 .input-content ::content .paper-input-input { | 190 .input-content ::content .paper-input-input { |
149 position: relative; /* to make a stacking context */ | 191 position: relative; /* to make a stacking context */ |
150 outline: none; | 192 outline: none; |
151 color: var(--paper-input-container-input-color); | 193 box-shadow: none; |
152 | |
153 mixin(--paper-input-container-floating-label-font); | |
154 } | |
155 | |
156 .input-content ::content input, | |
157 .input-content ::content textarea { | |
158 padding: 0; | 194 padding: 0; |
159 width: 100%; | 195 width: 100%; |
160 background: transparent; | 196 background: transparent; |
161 border: none; | 197 border: none; |
| 198 color: var(--paper-input-container-input-color, --primary-text-color); |
162 | 199 |
163 mixin(--paper-input-container-font); | 200 @apply(--paper-font-subhead); |
| 201 @apply(--paper-input-container-input); |
| 202 } |
164 | 203 |
165 mixin(--paper-input-container-input); | 204 /* Firefox sets a min-width on the input, which can cause layout issues */ |
| 205 .input-content ::content input { |
| 206 min-width: 0; |
166 } | 207 } |
167 | 208 |
168 .input-content ::content textarea { | 209 .input-content ::content textarea { |
169 resize: none; | 210 resize: none; |
170 } | 211 } |
171 | 212 |
172 .add-on-content.is-invalid ::content * { | 213 .add-on-content.is-invalid ::content * { |
173 color: var(--paper-input-container-invalid-color); | 214 color: var(--paper-input-container-invalid-color, --google-red-500); |
174 } | 215 } |
175 | 216 |
176 .add-on-content.is-highlighted ::content * { | 217 .add-on-content.is-highlighted ::content * { |
177 color: var(--paper-input-container-focus-color); | 218 color: var(--paper-input-container-focus-color, --default-primary-color); |
178 } | |
179 | |
180 .input-content, | |
181 .underline { | |
182 position: relative; | |
183 } | 219 } |
184 | 220 |
185 </style> | 221 </style> |
186 | 222 |
187 <template> | 223 <template> |
188 | 224 |
189 <template is="x-if" if="[[!noLabelFloat]]"> | 225 <template is="dom-if" if="[[!noLabelFloat]]"> |
190 <div class="floated-label-placeholder"> </div> | 226 <div class="floated-label-placeholder"> </div> |
191 </template> | 227 </template> |
192 | 228 |
193 <div class$="[[_computeInputContentClass(noLabelFloat,focused,_inputHasConte
nt,_inputIsInvalid)]]"> | 229 <div class$="[[_computeInputContentClass(noLabelFloat,alwaysFloatLabel,focus
ed,invalid,_inputHasContent)]]"> |
194 <content select=":not([add-on])"></content> | 230 <content select=":not([add-on])"></content> |
195 </div> | 231 </div> |
196 | 232 |
197 <div class$="[[_computeUnderlineClass(focused,_inputIsInvalid)]]"> | 233 <div class$="[[_computeUnderlineClass(focused,invalid)]]"> |
198 <div class="unfocused-line fit"></div> | 234 <div class="unfocused-line fit"></div> |
199 <div class="focused-line fit"></div> | 235 <div class="focused-line fit"></div> |
200 </div> | 236 </div> |
201 | 237 |
202 <div class$="[[_computeAddOnContentClass(focused,_inputIsInvalid)]]"> | 238 <div class$="[[_computeAddOnContentClass(focused,invalid)]]"> |
203 <content id="addOnContent" select="[add-on]"></content> | 239 <content id="addOnContent" select="[add-on]"></content> |
204 </div> | 240 </div> |
205 | 241 |
206 </template> | 242 </template> |
207 | 243 |
208 </dom-module> | 244 </dom-module> |
209 | 245 |
210 <script> | 246 <script> |
211 (function() { | 247 (function() { |
212 | 248 |
213 Polymer({ | 249 Polymer({ |
214 | 250 |
215 is: 'paper-input-container', | 251 is: 'paper-input-container', |
216 | 252 |
217 enableCustomStyleProperties: true, | |
218 | |
219 properties: { | 253 properties: { |
220 | 254 |
221 /** | 255 /** |
222 * Set to true to disable the floating label. | 256 * Set to true to disable the floating label. The label disappears when th
e input value is |
| 257 * not null. |
223 */ | 258 */ |
224 noLabelFloat: { | 259 noLabelFloat: { |
225 type: Boolean, | 260 type: Boolean, |
226 value: false | 261 value: false |
227 }, | 262 }, |
228 | 263 |
229 /** | 264 /** |
| 265 * Set to true to always float the floating label. |
| 266 */ |
| 267 alwaysFloatLabel: { |
| 268 type: Boolean, |
| 269 value: false |
| 270 }, |
| 271 |
| 272 /** |
230 * The attribute to listen for value changes on. | 273 * The attribute to listen for value changes on. |
231 */ | 274 */ |
232 attrForValue: { | 275 attrForValue: { |
233 type: String, | 276 type: String, |
234 value: 'bind-value' | 277 value: 'bind-value' |
235 }, | 278 }, |
236 | 279 |
237 /** | 280 /** |
238 * Set to true to auto-validate the input value. | 281 * Set to true to auto-validate the input value when it changes. |
239 */ | 282 */ |
240 autoValidate: { | 283 autoValidate: { |
241 type: Boolean, | 284 type: Boolean, |
242 value: false | 285 value: false |
243 }, | 286 }, |
244 | 287 |
245 /** | 288 /** |
| 289 * True if the input is invalid. This property is set automatically when t
he input value |
| 290 * changes if auto-validating, or when the `iron-input-valid` event is hea
rd from a child. |
| 291 */ |
| 292 invalid: { |
| 293 observer: '_invalidChanged', |
| 294 type: Boolean, |
| 295 value: false |
| 296 }, |
| 297 |
| 298 /** |
246 * True if the input has focus. | 299 * True if the input has focus. |
247 */ | 300 */ |
248 focused: { | 301 focused: { |
249 readOnly: true, | 302 readOnly: true, |
250 type: Boolean, | 303 type: Boolean, |
251 value: false | 304 value: false |
252 }, | 305 }, |
253 | 306 |
254 _addons: { | 307 _addons: { |
255 type: Array, | 308 type: Array, |
256 value: function() { | 309 value: function() { |
257 return []; | 310 return []; |
258 } | 311 } |
259 }, | 312 }, |
260 | 313 |
261 _inputHasContent: { | 314 _inputHasContent: { |
262 type: Boolean, | 315 type: Boolean, |
263 value: false | 316 value: false |
264 }, | 317 }, |
265 | 318 |
266 _inputIsInvalid: { | |
267 type: Boolean, | |
268 value: false | |
269 }, | |
270 | |
271 _inputSelector: { | 319 _inputSelector: { |
272 type: String, | 320 type: String, |
273 value: 'input,textarea,.paper-input-input' | 321 value: 'input,textarea,.paper-input-input' |
274 }, | 322 }, |
275 | 323 |
276 _boundOnFocus: { | 324 _boundOnFocus: { |
277 type: Function, | 325 type: Function, |
278 value: function() { | 326 value: function() { |
279 return this._onFocus.bind(this); | 327 return this._onFocus.bind(this); |
280 } | 328 } |
281 }, | 329 }, |
282 | 330 |
283 _boundOnBlur: { | 331 _boundOnBlur: { |
284 type: Function, | 332 type: Function, |
285 value: function() { | 333 value: function() { |
286 return this._onBlur.bind(this); | 334 return this._onBlur.bind(this); |
287 } | 335 } |
288 }, | 336 }, |
289 | 337 |
| 338 _boundOnInput: { |
| 339 type: Function, |
| 340 value: function() { |
| 341 this._onInput.bind(this) |
| 342 } |
| 343 }, |
| 344 |
290 _boundValueChanged: { | 345 _boundValueChanged: { |
291 type: Function, | 346 type: Function, |
292 value: function() { | 347 value: function() { |
293 return this._onValueChanged.bind(this); | 348 return this._onValueChanged.bind(this); |
294 } | 349 } |
295 } | 350 } |
296 | 351 |
297 }, | 352 }, |
298 | 353 |
299 listeners: { | 354 listeners: { |
300 'addon-attached': '_onAddonAttached', | 355 'addon-attached': '_onAddonAttached', |
301 'input': '_onInput' | 356 'iron-input-validate': '_onIronInputValidate' |
302 }, | 357 }, |
303 | 358 |
304 get _valueChangedEvent() { | 359 get _valueChangedEvent() { |
305 return this.attrForValue + '-changed'; | 360 return this.attrForValue + '-changed'; |
306 }, | 361 }, |
307 | 362 |
308 get _propertyForValue() { | 363 get _propertyForValue() { |
309 return Polymer.CaseMap.dashToCamelCase(this.attrForValue); | 364 return Polymer.CaseMap.dashToCamelCase(this.attrForValue); |
310 }, | 365 }, |
311 | 366 |
312 get _inputElement() { | 367 get _inputElement() { |
313 return Polymer.dom(this).querySelector(this._inputSelector); | 368 return Polymer.dom(this).querySelector(this._inputSelector); |
314 }, | 369 }, |
315 | 370 |
316 ready: function() { | 371 ready: function() { |
317 this.addEventListener('focus', this._boundOnFocus, true); | 372 this.addEventListener('focus', this._boundOnFocus, true); |
318 this.addEventListener('blur', this._boundOnBlur, true); | 373 this.addEventListener('blur', this._boundOnBlur, true); |
319 this.addEventListener(this._valueChangedEvent, this._boundValueChanged, tr
ue); | 374 if (this.attrForValue) { |
| 375 this._inputElement.addEventListener(this._valueChangedEvent, this._bound
ValueChanged); |
| 376 } else { |
| 377 this.addEventListener('input', this._onInput); |
| 378 } |
320 }, | 379 }, |
321 | 380 |
322 attached: function() { | 381 attached: function() { |
323 this._handleInput(this._inputElement); | 382 this._handleValue(this._inputElement); |
324 }, | 383 }, |
325 | 384 |
326 _onAddonAttached: function(event) { | 385 _onAddonAttached: function(event) { |
327 this._addons.push(event.target); | 386 this._addons.push(event.target); |
328 this._handleInput(this._inputElement); | 387 this._handleValue(this._inputElement); |
329 }, | 388 }, |
330 | 389 |
331 _onFocus: function() { | 390 _onFocus: function() { |
332 this._setFocused(true); | 391 this._setFocused(true); |
333 }, | 392 }, |
334 | 393 |
335 _onBlur: function() { | 394 _onBlur: function() { |
336 this._setFocused(false); | 395 this._setFocused(false); |
337 }, | 396 }, |
338 | 397 |
339 _onInput: function(event) { | 398 _onInput: function(event) { |
340 this._handleInput(event.target); | 399 this._handleValue(event.target); |
341 }, | 400 }, |
342 | 401 |
343 _onValueChanged: function(event) { | 402 _onValueChanged: function(event) { |
344 this._handleInput(event.target); | 403 this._handleValue(event.target); |
345 }, | 404 }, |
346 | 405 |
347 _handleInput: function(inputElement) { | 406 _handleValue: function(inputElement) { |
348 var value = inputElement[this._propertyForValue] || inputElement.value; | 407 var value = inputElement[this._propertyForValue] || inputElement.value; |
349 var valid = inputElement.checkValidity(); | 408 |
| 409 if (this.autoValidate) { |
| 410 var valid; |
| 411 if (inputElement.validate) { |
| 412 valid = inputElement.validate(value); |
| 413 } else { |
| 414 valid = inputElement.checkValidity(); |
| 415 } |
| 416 this.invalid = !valid; |
| 417 } |
350 | 418 |
351 // type="number" hack needed because this.value is empty until it's valid | 419 // type="number" hack needed because this.value is empty until it's valid |
352 if (value || inputElement.type === 'number' && !valid) { | 420 if (value || (inputElement.type === 'number' && !inputElement.checkValidit
y())) { |
353 this._inputHasContent = true; | 421 this._inputHasContent = true; |
354 } else { | 422 } else { |
355 this._inputHasContent = false; | 423 this._inputHasContent = false; |
356 } | 424 } |
357 | 425 |
358 if (this.autoValidate) { | 426 this.updateAddons({ |
359 this._inputIsInvalid = !valid; | 427 inputElement: inputElement, |
360 } | 428 value: value, |
| 429 invalid: this.invalid |
| 430 }); |
| 431 }, |
361 | 432 |
362 // notify add-ons | 433 _onIronInputValidate: function(event) { |
363 for (var addon, i = 0; addon = this._addons[i]; i++) { | 434 this.invalid = this._inputElement.invalid; |
364 // need to set all of these, or call method... thanks input type="number
"! | 435 }, |
365 addon.inputElement = inputElement; | 436 |
366 addon.value = value; | 437 _invalidChanged: function() { |
367 addon.invalid = !valid; | 438 if (this._addons) { |
| 439 this.updateAddons({invalid: this.invalid}); |
368 } | 440 } |
369 }, | 441 }, |
370 | 442 |
371 _computeInputContentClass: function(noLabelFloat, focused, _inputHasContent,
_inputIsInvalid) { | 443 /** |
| 444 * Call this to update the state of add-ons. |
| 445 * @param {Object} state Add-on state. |
| 446 */ |
| 447 updateAddons: function(state) { |
| 448 for (var addon, index = 0; addon = this._addons[index]; index++) { |
| 449 addon.update(state); |
| 450 } |
| 451 }, |
| 452 |
| 453 _computeInputContentClass: function(noLabelFloat, alwaysFloatLabel, focused,
invalid, _inputHasContent) { |
372 var cls = 'input-content'; | 454 var cls = 'input-content'; |
373 if (!noLabelFloat) { | 455 if (!noLabelFloat) { |
374 if (_inputHasContent) { | 456 if (alwaysFloatLabel || _inputHasContent) { |
375 cls += ' label-is-floating'; | 457 cls += ' label-is-floating'; |
376 if (_inputIsInvalid) { | 458 if (invalid) { |
377 cls += ' is-invalid'; | 459 cls += ' is-invalid'; |
378 } else if (focused) { | 460 } else if (focused) { |
379 cls += " label-is-highlighted"; | 461 cls += " label-is-highlighted"; |
380 } | 462 } |
381 } | 463 } |
382 } else { | 464 } else { |
383 if (_inputHasContent) { | 465 if (_inputHasContent) { |
384 cls += ' label-is-hidden'; | 466 cls += ' label-is-hidden'; |
385 } | 467 } |
386 } | 468 } |
387 return cls; | 469 return cls; |
388 }, | 470 }, |
389 | 471 |
390 _computeUnderlineClass: function(focused, _inputIsInvalid) { | 472 _computeUnderlineClass: function(focused, invalid) { |
391 var cls = 'underline'; | 473 var cls = 'underline'; |
392 if (_inputIsInvalid) { | 474 if (invalid) { |
393 cls += ' is-invalid'; | 475 cls += ' is-invalid'; |
394 } else if (focused) { | 476 } else if (focused) { |
395 cls += ' is-highlighted' | 477 cls += ' is-highlighted' |
396 } | 478 } |
397 return cls; | 479 return cls; |
398 }, | 480 }, |
399 | 481 |
400 _computeAddOnContentClass: function(focused, _inputIsInvalid) { | 482 _computeAddOnContentClass: function(focused, invalid) { |
401 var cls = 'add-on-content'; | 483 var cls = 'add-on-content'; |
402 if (_inputIsInvalid) { | 484 if (invalid) { |
403 cls += ' is-invalid'; | 485 cls += ' is-invalid'; |
404 } else if (focused) { | 486 } else if (focused) { |
405 cls += ' is-highlighted' | 487 cls += ' is-highlighted' |
406 } | 488 } |
407 return cls; | 489 return cls; |
408 } | 490 } |
409 | 491 |
410 }); | 492 }); |
411 | 493 |
412 })(); | 494 })(); |
413 </script> | 495 </script> |
OLD | NEW |