polymer-paper-rails 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +19 -18
  3. data/app/assets/components/core-a11y-keys/core-a11y-keys.html +4 -4
  4. data/app/assets/components/core-animation/web-animations.html +1 -1
  5. data/app/assets/components/core-collapse/core-collapse.html +1 -1
  6. data/app/assets/components/core-drawer-panel/core-drawer-panel.css +14 -6
  7. data/app/assets/components/core-drawer-panel/core-drawer-panel.html +32 -8
  8. data/app/assets/components/core-dropdown/core-dropdown.html +8 -2
  9. data/app/assets/components/core-icon/core-icon.html +0 -2
  10. data/app/assets/components/core-icons/av-icons.html +2 -9
  11. data/app/assets/components/core-icons/communication-icons.html +39 -42
  12. data/app/assets/components/core-icons/core-icons.html +231 -235
  13. data/app/assets/components/core-icons/device-icons.html +75 -90
  14. data/app/assets/components/core-icons/editor-icons.html +52 -52
  15. data/app/assets/components/core-icons/hardware-icons.html +40 -41
  16. data/app/assets/components/core-icons/image-icons.html +133 -137
  17. data/app/assets/components/core-icons/maps-icons.html +55 -57
  18. data/app/assets/components/core-icons/notification-icons.html +34 -34
  19. data/app/assets/components/core-icons/social-icons.html +23 -37
  20. data/app/assets/components/core-menu/core-menu.html +8 -3
  21. data/app/assets/components/core-menu/core-submenu.html +2 -2
  22. data/app/assets/components/core-overlay/core-key-helper.html +3 -0
  23. data/app/assets/components/core-overlay/core-overlay-layer.html +3 -0
  24. data/app/assets/components/core-overlay/core-overlay.html +20 -4
  25. data/app/assets/components/core-resizable/core-resizable.html +248 -0
  26. data/app/assets/components/core-scroll-header-panel/core-scroll-header-panel.html +14 -3
  27. data/app/assets/components/core-selection/core-selection.html +1 -1
  28. data/app/assets/components/core-selector/core-selector.html +26 -26
  29. data/app/assets/components/core-style/core-style.html +1 -1
  30. data/app/assets/components/core-toolbar/core-toolbar.html +1 -1
  31. data/app/assets/components/paper-button/paper-button-base.html +56 -12
  32. data/app/assets/components/paper-button/paper-button.html +22 -5
  33. data/app/assets/components/paper-checkbox/paper-checkbox.css +65 -184
  34. data/app/assets/components/paper-checkbox/paper-checkbox.html +47 -55
  35. data/app/assets/components/paper-dialog/paper-action-dialog.html +3 -3
  36. data/app/assets/components/paper-dialog/paper-dialog.html +2 -2
  37. data/app/assets/components/paper-dropdown-menu/paper-dropdown-menu.html +4 -1
  38. data/app/assets/components/{core-elements → paper-elements}/metadata.html +0 -0
  39. data/app/assets/components/{core-elements → paper-elements}/paper-elements.html +1 -0
  40. data/app/assets/components/paper-fab/paper-fab.html +2 -2
  41. data/app/assets/components/paper-input/paper-autogrow-textarea.html +8 -3
  42. data/app/assets/components/paper-input/paper-char-counter.html +121 -0
  43. data/app/assets/components/paper-input/paper-input-decorator.css +1 -21
  44. data/app/assets/components/paper-input/paper-input-decorator.html +130 -51
  45. data/app/assets/components/paper-input/paper-input.html +31 -5
  46. data/app/assets/components/paper-item/paper-item.html +1 -2
  47. data/app/assets/components/paper-progress/paper-progress.html +1 -1
  48. data/app/assets/components/paper-radio-button/paper-radio-button.css +16 -12
  49. data/app/assets/components/paper-radio-button/paper-radio-button.html +9 -3
  50. data/app/assets/components/paper-ripple/paper-ripple.html +2 -1
  51. data/app/assets/components/paper-shadow/paper-shadow.css +10 -10
  52. data/app/assets/components/paper-shadow/paper-shadow.html +8 -1
  53. data/app/assets/components/paper-slider/paper-slider.html +28 -4
  54. data/app/assets/components/paper-spinner/paper-spinner.css +35 -23
  55. data/app/assets/components/paper-spinner/paper-spinner.html +46 -5
  56. data/app/assets/components/paper-tabs/paper-tabs.css +5 -0
  57. data/app/assets/components/paper-tabs/paper-tabs.html +32 -7
  58. data/app/assets/components/paper-toggle-button/paper-toggle-button.css +58 -30
  59. data/app/assets/components/paper-toggle-button/paper-toggle-button.html +69 -44
  60. data/app/assets/components/sampler-scaffold/sampler-scaffold.css +1 -1
  61. data/app/assets/components/web-animations-js/web-animations-next-lite.min.js +17 -0
  62. data/app/assets/components/web-animations-js/web-animations-next.min.js +17 -0
  63. data/app/assets/components/web-animations-js/web-animations.min.js +17 -0
  64. data/app/assets/components/webcomponentsjs/CustomElements.js +634 -0
  65. data/app/assets/components/webcomponentsjs/CustomElements.min.js +11 -0
  66. data/app/assets/components/webcomponentsjs/HTMLImports.js +764 -0
  67. data/app/assets/components/webcomponentsjs/HTMLImports.min.js +11 -0
  68. data/app/assets/components/webcomponentsjs/ShadowDOM.js +4277 -0
  69. data/app/assets/components/webcomponentsjs/ShadowDOM.min.js +13 -0
  70. data/app/assets/components/webcomponentsjs/package.json +31 -0
  71. data/app/assets/components/webcomponentsjs/webcomponents-lite.js +1728 -0
  72. data/app/assets/components/webcomponentsjs/webcomponents-lite.min.js +11 -0
  73. data/app/assets/components/webcomponentsjs/webcomponents.js +6114 -0
  74. data/app/assets/components/webcomponentsjs/webcomponents.min.js +14 -0
  75. data/lib/polymer-paper-rails/version.rb +1 -1
  76. metadata +20 -71
  77. data/app/assets/components/core-dropdown/metadata.html +0 -62
  78. data/app/assets/components/core-icons/png-icons.html +0 -19
  79. data/app/assets/components/core-label/core-label.html +0 -124
  80. data/app/assets/components/core-overlay/tests/html/core-overlay-basic.html +0 -127
  81. data/app/assets/components/core-overlay/tests/html/core-overlay-positioning-margin.html +0 -153
  82. data/app/assets/components/core-overlay/tests/html/core-overlay-positioning.html +0 -167
  83. data/app/assets/components/core-overlay/tests/html/core-overlay-scroll.html +0 -130
  84. data/app/assets/components/core-overlay/tests/js/htmltests.js +0 -6
  85. data/app/assets/components/core-overlay/tests/runner.html +0 -14
  86. data/app/assets/components/core-overlay/tests/tests.json +0 -6
  87. data/app/assets/components/core-popup-menu/core-popup-menu.css +0 -28
  88. data/app/assets/components/core-popup-menu/core-popup-menu.html +0 -198
  89. data/app/assets/components/core-popup-menu/core-popup-overlay.html +0 -111
  90. data/app/assets/components/core-popup-menu/metadata.html +0 -62
  91. data/app/assets/components/paper-focusable/paper-focusable.html +0 -146
  92. data/app/assets/components/platform/platform.js +0 -16
  93. data/app/assets/components/web-animations-js/web-animations.js +0 -5529
  94. data/app/assets/components/web-animations-next/Gruntfile.js +0 -279
  95. data/app/assets/components/web-animations-next/History.md +0 -76
  96. data/app/assets/components/web-animations-next/package.json +0 -33
  97. data/app/assets/components/web-animations-next/src/animation-constructor.js +0 -139
  98. data/app/assets/components/web-animations-next/src/animation-node.js +0 -31
  99. data/app/assets/components/web-animations-next/src/animation.js +0 -65
  100. data/app/assets/components/web-animations-next/src/apply-preserving-inline-style.js +0 -192
  101. data/app/assets/components/web-animations-next/src/apply.js +0 -25
  102. data/app/assets/components/web-animations-next/src/box-handler.js +0 -57
  103. data/app/assets/components/web-animations-next/src/color-handler.js +0 -62
  104. data/app/assets/components/web-animations-next/src/deprecation.js +0 -42
  105. data/app/assets/components/web-animations-next/src/dev.js +0 -16
  106. data/app/assets/components/web-animations-next/src/dimension-handler.js +0 -167
  107. data/app/assets/components/web-animations-next/src/effect-callback.js +0 -86
  108. data/app/assets/components/web-animations-next/src/effect.js +0 -110
  109. data/app/assets/components/web-animations-next/src/element-animatable.js +0 -19
  110. data/app/assets/components/web-animations-next/src/font-weight-handler.js +0 -42
  111. data/app/assets/components/web-animations-next/src/group-constructors.js +0 -81
  112. data/app/assets/components/web-animations-next/src/handler-utils.js +0 -177
  113. data/app/assets/components/web-animations-next/src/interpolation.js +0 -49
  114. data/app/assets/components/web-animations-next/src/matrix-decomposition.js +0 -452
  115. data/app/assets/components/web-animations-next/src/matrix-interpolation.js +0 -130
  116. data/app/assets/components/web-animations-next/src/maxifill-player.js +0 -162
  117. data/app/assets/components/web-animations-next/src/normalize-keyframes.js +0 -259
  118. data/app/assets/components/web-animations-next/src/number-handler.js +0 -72
  119. data/app/assets/components/web-animations-next/src/player.js +0 -193
  120. data/app/assets/components/web-animations-next/src/position-handler.js +0 -117
  121. data/app/assets/components/web-animations-next/src/property-interpolation.js +0 -62
  122. data/app/assets/components/web-animations-next/src/property-names.js +0 -35
  123. data/app/assets/components/web-animations-next/src/scope.js +0 -20
  124. data/app/assets/components/web-animations-next/src/shadow-handler.js +0 -108
  125. data/app/assets/components/web-animations-next/src/shape-handler.js +0 -85
  126. data/app/assets/components/web-animations-next/src/tick.js +0 -148
  127. data/app/assets/components/web-animations-next/src/timeline.js +0 -77
  128. data/app/assets/components/web-animations-next/src/timing-utilities.js +0 -242
  129. data/app/assets/components/web-animations-next/src/transform-handler.js +0 -262
  130. data/app/assets/components/web-animations-next/src/visibility-handler.js +0 -29
  131. data/app/assets/components/web-animations-next/target-config.js +0 -124
  132. data/app/assets/components/web-animations-next/target-loader.js +0 -13
  133. data/app/assets/components/web-animations-next/templates/boilerplate +0 -13
  134. data/app/assets/components/web-animations-next/templates/runner.html +0 -26
  135. data/app/assets/components/web-animations-next/templates/web-animations.html +0 -18
  136. data/app/assets/components/web-animations-next/templates/web-animations.js +0 -21
  137. data/app/assets/components/web-animations-next/web-animations-next-lite.dev.html +0 -44
  138. data/app/assets/components/web-animations-next/web-animations-next-lite.dev.js +0 -21
  139. data/app/assets/components/web-animations-next/web-animations-next.dev.html +0 -49
  140. data/app/assets/components/web-animations-next/web-animations-next.dev.js +0 -21
  141. data/app/assets/components/web-animations-next/web-animations.dev.html +0 -44
  142. data/app/assets/components/web-animations-next/web-animations.dev.js +0 -21
  143. data/app/assets/components/web-animations-next/web-animations.html +0 -50
@@ -62,7 +62,7 @@ By default, the `aria-label` will be set to the value of the `heading` attribute
62
62
 
63
63
  <link href="paper-dialog-base.html" rel="import">
64
64
 
65
- <polymer-element name="paper-dialog" extends="paper-dialog-base" role="dialog" noscript>
65
+ <polymer-element name="paper-dialog" extends="paper-dialog-base" role="dialog" layout vertical noscript>
66
66
 
67
67
  <template>
68
68
 
@@ -88,7 +88,7 @@ By default, the `aria-label` will be set to the value of the `heading` attribute
88
88
  <paper-shadow z="3" fit></paper-shadow>
89
89
 
90
90
  <!-- need this because the host needs to be overflow: visible -->
91
- <div id="scroller" relative>
91
+ <div id="scroller" relative flex auto>
92
92
  <template if="{{heading}}">
93
93
  <h1>{{heading}}</h1>
94
94
  </template>
@@ -36,6 +36,7 @@ This example renders a drop-down menu with 4 options.
36
36
  @group Paper Elements
37
37
  @element paper-dropdown-menu
38
38
  @extends core-dropdown-base
39
+ @mixins Polymer.CoreFocusable https://github.com/polymer/core-focusable
39
40
  @status unstable
40
41
  @homepage github.io
41
42
  -->
@@ -93,7 +94,7 @@ contains the selection state.
93
94
  outline: none;
94
95
  }
95
96
 
96
- #label, #arrow {
97
+ #label:not(.selectedItem), #arrow {
97
98
  color: #757575;
98
99
  }
99
100
 
@@ -164,8 +165,10 @@ contains the selection state.
164
165
  selectAction: function(e) {
165
166
  var detail = e.detail;
166
167
  if (detail.isSelected) {
168
+ this.$.label.classList.add('selectedItem');
167
169
  this.selectedItemLabel = detail.item.label || detail.item.textContent;
168
170
  } else {
171
+ this.$.label.classList.remove('selectedItem');
169
172
  this.selectedItemLabel = '';
170
173
  }
171
174
  }
@@ -19,6 +19,7 @@ See `bower.json` for the complete list of components.
19
19
  <link rel="import" href="../polymer/polymer.html">
20
20
  <link rel="import" href="../paper-button/paper-button.html">
21
21
  <link rel="import" href="../paper-checkbox/paper-checkbox.html">
22
+ <link rel="import" href="../paper-dialog/paper-action-dialog.html">
22
23
  <link rel="import" href="../paper-dialog/paper-dialog.html">
23
24
  <link rel="import" href="../paper-dropdown/paper-dropdown.html">
24
25
  <link rel="import" href="../paper-dropdown-menu/paper-dropdown-menu.html">
@@ -162,8 +162,8 @@ you should ensure that the `aria-label` attribute is set.
162
162
  mini: false,
163
163
 
164
164
  raised: true,
165
- recenteringTouch: false,
166
- fill: true
165
+ recenteringTouch: true,
166
+ fill: false
167
167
 
168
168
  },
169
169
 
@@ -16,7 +16,7 @@ Example:
16
16
 
17
17
  <paper-autogrow-textarea id="a1">
18
18
  <textarea id="t1"></textarea>
19
- <paper-autogrow-textarea>
19
+ </paper-autogrow-textarea>
20
20
 
21
21
  Because the `textarea`'s `value` property is not observable, if you set the `value` imperatively
22
22
  you must call `update` to notify this element the value has changed.
@@ -44,6 +44,11 @@ Example:
44
44
  width: 400px;
45
45
  }
46
46
 
47
+ .mirror-text {
48
+ visibility: hidden;
49
+ word-wrap: break-word;
50
+ }
51
+
47
52
  ::content textarea {
48
53
  padding: 0;
49
54
  margin: 0;
@@ -61,7 +66,7 @@ Example:
61
66
  </style>
62
67
 
63
68
  <!-- the mirror sizes the input/textarea so it grows with typing -->
64
- <div id="mirror" class="mirror-text" invisible aria-hidden="true">&nbsp;</div>
69
+ <div id="mirror" class="mirror-text" aria-hidden="true">&nbsp;</div>
65
70
 
66
71
  <!-- size the input/textarea with a div, because the textarea has intrinsic size in ff -->
67
72
  <div class="textarea-container" fit>
@@ -154,4 +159,4 @@ Example:
154
159
  });
155
160
 
156
161
  </script>
157
- </polymer-element>
162
+ </polymer-element>
@@ -0,0 +1,121 @@
1
+ <!--
2
+ Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
3
+ This code may only be used under the BSD style license found at http://polymer.github.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/CONTRIBUTORS
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/PATENTS
8
+ -->
9
+
10
+ <!--
11
+
12
+ Material Design: <a href="http://www.google.com/design/spec/components/text-fields.html#text-fields-character-counter">Character counter</a>
13
+
14
+ `paper-char-counter` adds a character counter for paper input fields with a character restriction in place.
15
+
16
+ Example:
17
+
18
+ <paper-input-decorator>
19
+ <input id="input1" is="core-input" maxlength="5">
20
+ <paper-char-counter class="footer" target="input1"></paper-char-counter>
21
+ </paper-input-decorator>
22
+
23
+ Theming
24
+ -------
25
+
26
+ `paper-char-counter` uses `paper-input-decorator`'s error `core-style` for global theming.
27
+
28
+ @group Paper Elements
29
+ @element paper-char-counter
30
+ @homepage github.io
31
+ -->
32
+ <link href="../polymer/polymer.html" rel="import">
33
+ <link href="../core-style/core-style.html" rel="import">
34
+
35
+ <core-style id="paper-char-counter">
36
+ :host(.invalid) {
37
+ color: {{g.paperInput.invalidColor}};
38
+ }
39
+ </core-style>
40
+
41
+ <polymer-element name="paper-char-counter">
42
+
43
+ <template>
44
+
45
+ <style>
46
+ :host {
47
+ display: inline-block;
48
+ float: right;
49
+ color: #757575;
50
+ font-size: 0.75em;
51
+ padding: 0.5em 0 0.5em 0.5em;
52
+ }
53
+ </style>
54
+
55
+ <core-style ref="paper-char-counter"></core-style>
56
+
57
+ <div class="counter-text" aria-hidden="true" hidden?="{{!showCounter || !_maxChars}}">
58
+ <span>{{_charCount}} / {{_maxChars}}</span>
59
+ </div>
60
+
61
+ </template>
62
+
63
+ <script>
64
+
65
+ Polymer({
66
+
67
+ publish: {
68
+ /**
69
+ * The id of the textinput or textarea that should be monitored.
70
+ *
71
+ * @attribute target
72
+ * @type string
73
+ * @default null
74
+ */
75
+ target: null,
76
+
77
+ /**
78
+ * If false, don't show the character counter. Used in conjunction with
79
+ * `paper-input-decorator's` `error` field.
80
+ *
81
+ * @attribute showCounter
82
+ * @type boolean
83
+ * @default true
84
+ */
85
+ showCounter: true
86
+ },
87
+
88
+ /* Number of characters in the current input */
89
+ _charCount: 0,
90
+
91
+ /* Equal to the target element's maxLength attribute. */
92
+ _maxChars: 0,
93
+
94
+ /* True if the number of characters in the input exceeds _maxChars */
95
+ _isCounterInvalid: false,
96
+
97
+ ready: function() {
98
+ if (!this.target)
99
+ return;
100
+ var targetElement = document.getElementById(this.target);
101
+ this._maxChars = targetElement.maxLength;
102
+ targetElement.addEventListener('input', this.inputAction.bind(this));
103
+ },
104
+
105
+ inputAction: function(e) {
106
+ this._charCount = e.target.value.length;
107
+ this._isCounterInvalid = this._maxChars && this._charCount >= this._maxChars;
108
+ },
109
+
110
+ _isCounterInvalidChanged: function() {
111
+ debugger
112
+ this.classList.toggle('invalid', this._isCounterInvalid);
113
+ this.fire('char-counter-error',
114
+ {"hasError": this._isCounterInvalid,
115
+ "hideErrorIcon": this.showCounter});
116
+ }
117
+ });
118
+
119
+ </script>
120
+
121
+ </polymer-element>
@@ -16,7 +16,7 @@
16
16
  }
17
17
 
18
18
  polyfill-next-selector {
19
- content: '.input-body > :not(.label):not(.cursor)';
19
+ content: '.input-body > :not(.label)';
20
20
  }
21
21
  ::content > *,
22
22
  ::content > input[is="core-input"] {
@@ -97,26 +97,6 @@ polyfill-next-selector {
97
97
  transform-origin: 0% 0%;
98
98
  }
99
99
 
100
- .cursor {
101
- position: absolute;
102
- top: 0.4em;
103
- left: 0;
104
- width: 1px;
105
- height: 1.4em;
106
- opacity: 0.4;
107
- -moz-transform-origin: 0%;
108
- -webkit-transform-origin: 0%;
109
- transform-origin: 0%;
110
- -webkit-transform: none;
111
- transform: none;
112
- }
113
-
114
- .cursor[invisible] {
115
- opacity: 0.75;
116
- -webkit-transform: translate3d(3em,0,0) scale3d(50,1,1);
117
- transform: translate3d(3em,0,0) scale3d(50,1,1);
118
- }
119
-
120
100
  .underline {
121
101
  height: 0px;
122
102
  overflow: visible;
@@ -30,8 +30,7 @@ Theming
30
30
 
31
31
  - `CoreStyle.g.paperInput.labelColor` - The inline label, floating label, error message and error icon color when the input does not have focus.
32
32
  - `CoreStyle.g.paperInput.focusedColor` - The floating label and the underline color when the input has focus.
33
- - `CoreStyle.g.paperInput.cursorColor` - The cursor color during the focus animation. Typically this is the same as `focusedColor`.
34
- - `CoreStyle.g.paperInput.invalidColor` - The error message, the error icon, the cursor, the floating label and the underline's color when the input is invalid and 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 focus.
35
34
 
36
35
  To add custom styling to only some elements, use these selectors:
37
36
 
@@ -67,20 +66,14 @@ To add custom styling to only some elements, use these selectors:
67
66
  background-color: orange;
68
67
  }
69
68
 
70
- paper-input-decorator /deep/ .cursor {
71
- /* cursor color during the focus transition */
72
- background-color: orange;
73
- }
74
-
75
69
  paper-input-decorator.invalid[focused] /deep/ .floated-label .label-text,
76
70
  paper-input-decorator[focused] /deep/ .error {
77
71
  /* floating label, error message nad error icon color when the input is invalid and focused */
78
72
  color: salmon;
79
73
  }
80
74
 
81
- paper-input-decorator.invalid /deep/ .focused-underline,
82
- paper-input-decorator.invalid /deep/ .cursor {
83
- /* line and cursor color when the input is invalid and focused */
75
+ paper-input-decorator.invalid /deep/ .focused-underline {
76
+ /* line and color when the input is invalid and focused */
84
77
  background-color: salmon;
85
78
  }
86
79
 
@@ -89,6 +82,36 @@ Form submission
89
82
 
90
83
  You can use inputs decorated with this element in a `form` as usual.
91
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/Constraint_validation">HTML5 Constraints Validation API</a>
90
+ to implement validation. Set the `isInvalid` attribute when the input is validated, 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
+
92
115
  Accessibility
93
116
  -------------
94
117
 
@@ -137,18 +160,13 @@ conflict with this element.
137
160
  background-color: {{g.paperInput.focusedColor}};
138
161
  }
139
162
 
140
- .cursor {
141
- background-color: {{g.paperInput.cursorColor}};
142
- }
143
-
144
163
  :host(.invalid) .floated-label .label-text,
145
164
  .error {
146
165
  color: {{g.paperInput.invalidColor}};
147
166
  }
148
167
 
149
168
  :host(.invalid) .unfocused-underline,
150
- :host(.invalid) .focused-underline,
151
- :host(.invalid) .cursor {
169
+ :host(.invalid) .focused-underline {
152
170
  background-color: {{g.paperInput.invalidColor}};
153
171
  }
154
172
 
@@ -157,7 +175,9 @@ conflict with this element.
157
175
  <polymer-element name="paper-input-decorator" layout vertical
158
176
  on-transitionEnd="{{transitionEndAction}}" on-webkitTransitionEnd="{{transitionEndAction}}"
159
177
  on-input="{{inputAction}}"
160
- on-down="{{downAction}}">
178
+ on-down="{{downAction}}"
179
+ on-tap="{{tapAction}}"
180
+ on-char-counter-error="{{charCounterErrorAction}}">
161
181
 
162
182
  <template>
163
183
 
@@ -176,20 +196,23 @@ conflict with this element.
176
196
  <span id="labelText" class="label-text" invisible?="{{!_labelVisible}}" animated?="{{labelAnimated}}">{{label}}</span>
177
197
  </div>
178
198
 
179
- <div class="cursor" invisible?="{{!cursorAnimated}}" animated?="{{cursorAnimated}}"></div>
180
-
181
- <content></content>
199
+ <content select="*:not(.counter)"></content>
182
200
 
183
201
  </div>
184
202
 
185
203
  <div id="underline" class="underline" relative>
186
204
  <div class="unfocused-underline" fit invisible?="{{disabled}}"></div>
187
- <div id="focusedUnderline" class="focused-underline" fit invisible?="{{!focused}}" animated?="{{underlineAnimated}}"></div>
205
+ <div id="focusedUnderline" class="focused-underline" fit invisible?="{{!underlineVisible}}" animated?="{{underlineAnimated}}"></div>
188
206
  </div>
189
207
 
190
- <div class="error" layout horizontal center hidden?="{{!isInvalid}}">
191
- <div class="error-text" flex auto role="alert" aria-hidden="{{!isInvalid}}">{{error}}</div>
192
- <core-icon class="error-icon" icon="warning"></core-icon>
208
+ <div class="footer" layout horizontal end-justified>
209
+ <div class="error" flex layout horizontal center hidden?="{{!isInvalid}}">
210
+ <div class="error-text" flex auto role="alert" aria-hidden="{{!isInvalid}}">{{error}}</div>
211
+ <core-icon id="errorIcon" class="error-icon" icon="warning"></core-icon>
212
+ </div>
213
+ <div aria-hidden="true">
214
+ <content select=".counter"></content>
215
+ </div>
193
216
  </div>
194
217
 
195
218
  </template>
@@ -201,7 +224,6 @@ conflict with this element.
201
224
  var paperInput = CoreStyle.g.paperInput = CoreStyle.g.paperInput || {};
202
225
 
203
226
  paperInput.labelColor = '#757575';
204
- paperInput.cursorColor = '#4059a9';
205
227
  paperInput.focusedColor = '#4059a9';
206
228
  paperInput.invalidColor = '#d34336';
207
229
 
@@ -259,6 +281,17 @@ conflict with this element.
259
281
  */
260
282
  isInvalid: false,
261
283
 
284
+ /**
285
+ * Set this property to true to validate the input as the user types.
286
+ * This will not validate when changing the input programmatically; call
287
+ * `validate()` instead.
288
+ *
289
+ * @attribute autoValidate
290
+ * @type boolean
291
+ * @default false
292
+ */
293
+ autoValidate: false,
294
+
262
295
  /**
263
296
  * The message to display if the input value fails validation. If this
264
297
  * is unset or the empty string, a default message is displayed depending
@@ -311,7 +344,7 @@ conflict with this element.
311
344
 
312
345
  animateFloatingLabel: function() {
313
346
  if (!this.floatingLabel || this.labelAnimated) {
314
- return;
347
+ return false;
315
348
  }
316
349
 
317
350
  if (!this.$.labelText.cachedTransform) {
@@ -321,7 +354,7 @@ conflict with this element.
321
354
  // If there's still no cached transform, the input is invisible so don't
322
355
  // do the animation.
323
356
  if (!this.$.labelText.cachedTransform) {
324
- return;
357
+ return false;
325
358
  }
326
359
 
327
360
  this.labelAnimated = true;
@@ -345,12 +378,47 @@ conflict with this element.
345
378
  this.input.placeholder = '';
346
379
  }
347
380
 
381
+ return true;
382
+ },
383
+
384
+ animateUnderline: function(e) {
385
+ if (this.focused) {
386
+ var rect = this.$.underline.getBoundingClientRect();
387
+ var right = e.x - rect.left;
388
+ this.$.focusedUnderline.style.mozTransformOrigin = right + 'px';
389
+ this.$.focusedUnderline.style.webkitTransformOrigin = right + 'px ';
390
+ this.$.focusedUnderline.style.transformOriginX = right + 'px';
391
+
392
+ // Animations only run when the user interacts with the input
393
+ this.underlineAnimated = true;
394
+ }
395
+ },
396
+
397
+ /**
398
+ * Validate the input using HTML5 Constraints.
399
+ *
400
+ * @method validate
401
+ * @return {boolean} True if the input is valid.
402
+ */
403
+ validate: function() {
404
+ this.isInvalid = !this.input.validity.valid;
405
+ return this.input.validity.valid;
348
406
  },
349
407
 
350
408
  _labelVisibleChanged: function(old) {
351
409
  // do not do the animation on first render
352
410
  if (old !== undefined) {
353
- this.animateFloatingLabel();
411
+ if (!this.animateFloatingLabel()) {
412
+ this.updateInputLabel(this.input, this.label);
413
+ }
414
+ }
415
+ },
416
+
417
+ labelVisibleChanged: function() {
418
+ if (this.labelVisible === 'true') {
419
+ this.labelVisible = true;
420
+ } else if (this.labelVisible === 'false') {
421
+ this.labelVisible = false;
354
422
  }
355
423
  },
356
424
 
@@ -366,12 +434,21 @@ conflict with this element.
366
434
 
367
435
  focusedChanged: function() {
368
436
  this.updateLabelVisibility(this.input && this.input.value);
437
+ if (this.lastEvent) {
438
+ this.animateUnderline(this.lastEvent);
439
+ this.lastEvent = null;
440
+ }
441
+ this.underlineVisible = this.focused;
369
442
  },
370
443
 
371
444
  inputChanged: function(old) {
372
445
  if (this.input) {
373
446
  this.updateLabelVisibility(this.input.value);
374
447
  this.updateInputLabel(this.input, this.label);
448
+
449
+ if (this.autoValidate) {
450
+ this.validate();
451
+ }
375
452
  }
376
453
  if (old) {
377
454
  this.updateInputLabel(old, '');
@@ -382,7 +459,7 @@ conflict with this element.
382
459
  this.focused = true;
383
460
  },
384
461
 
385
- blurAction: function(e) {
462
+ blurAction: function() {
386
463
  this.focused = false;
387
464
  },
388
465
 
@@ -412,11 +489,25 @@ conflict with this element.
412
489
  }
413
490
  },
414
491
 
415
- inputAction: function(e) {
416
- this.updateLabelVisibility(e.target.value);
492
+ inputAction: function() {
493
+ this.updateLabelVisibility(this.input.value);
494
+ if (this.autoValidate) {
495
+ this.validate();
496
+ }
417
497
  },
418
498
 
419
499
  downAction: function(e) {
500
+ // eat the event and do nothing if already focused
501
+ if (e.target !== this.input && this.focused) {
502
+ e.preventDefault();
503
+ return;
504
+ }
505
+ // cache the event here because "down" fires before "focus" when tapping on
506
+ // the input and the underline animation runs on focus change
507
+ this.lastEvent = e;
508
+ },
509
+
510
+ tapAction: function(e) {
420
511
  if (this.disabled) {
421
512
  return;
422
513
  }
@@ -429,34 +520,22 @@ conflict with this element.
429
520
  this.input.focus();
430
521
  e.preventDefault();
431
522
  }
432
-
433
- // The underline spills from the tap location
434
- var rect = this.$.underline.getBoundingClientRect();
435
- var right = e.x - rect.left;
436
- this.$.focusedUnderline.style.mozTransformOrigin = right + 'px';
437
- this.$.focusedUnderline.style.webkitTransformOrigin = right + 'px ';
438
- this.$.focusedUnderline.style.transformOriginX = right + 'px';
439
-
440
- // Animations only run when the user interacts with the input
441
- this.underlineAnimated = true;
442
-
443
- // Cursor animation only runs if the input is empty
444
- if (this._labelVisible) {
445
- this.cursorAnimated = true;
446
- }
447
- // Handle interrupted animation
448
- this.async(function() {
449
- this.transitionEndAction();
450
- }, null, 250);
451
523
  },
452
524
 
453
525
  transitionEndAction: function() {
454
526
  this.underlineAnimated = false;
455
- this.cursorAnimated = false;
456
527
  this.labelAnimated = false;
457
528
  if (this._labelVisible) {
458
529
  this.input.placeholder = this.label;
459
530
  }
531
+ },
532
+
533
+ charCounterErrorAction: function(e) {
534
+ this.isInvalid = e.detail.hasError;
535
+
536
+ // If the allowed characters have been exceeded, show either the error
537
+ // icon, or the character counter, but not both.
538
+ this.$.errorIcon.hidden = e.detail.hideErrorIcon;
460
539
  }
461
540
 
462
541
  });