| Index: polymer_0.5.0/bower_components/paper-input/paper-input-decorator.html
|
| diff --git a/polymer_0.5.0/bower_components/paper-input/paper-input-decorator.html b/polymer_0.5.0/bower_components/paper-input/paper-input-decorator.html
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6a9f954fbe1ba449bafacfe7ab5d0074ee97f9a2
|
| --- /dev/null
|
| +++ b/polymer_0.5.0/bower_components/paper-input/paper-input-decorator.html
|
| @@ -0,0 +1,489 @@
|
| +<!--
|
| +Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
| +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
|
| +The complete set of authors may be found at http://polymer.github.io/AUTHORS
|
| +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
|
| +Code distributed by Google as part of the polymer project is also
|
| +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
|
| +-->
|
| +
|
| +<!--
|
| +
|
| +Material Design: <a href="http://www.google.com/design/spec/components/text-fields.html">Text fields</a>
|
| +
|
| +`paper-input-decorator` adds Material Design input field styling and animations to an element.
|
| +
|
| +Example:
|
| +
|
| + <paper-input-decorator label="Your Name">
|
| + <input is="core-input">
|
| + </paper-input-decorator>
|
| +
|
| + <paper-input-decorator floatingLabel label="Your address">
|
| + <textarea></textarea>
|
| + </paper-input-decorator>
|
| +
|
| +Theming
|
| +-------
|
| +
|
| +`paper-input-decorator` uses `core-style` for global theming. The following options are available:
|
| +
|
| +- `CoreStyle.g.paperInput.labelColor` - The inline label, floating label, error message and error icon color when the input does not have focus.
|
| +- `CoreStyle.g.paperInput.focusedColor` - The floating label and the underline color when the input has focus.
|
| +- `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.
|
| +
|
| +To add custom styling to only some elements, use these selectors:
|
| +
|
| + paper-input-decorator /deep/ .label-text,
|
| + paper-input-decorator /deep/ .error {
|
| + /* inline label, floating label, error message and error icon color when the input is unfocused */
|
| + color: green;
|
| + }
|
| +
|
| + paper-input-decorator /deep/ ::-webkit-input-placeholder {
|
| + /* platform specific rules for placeholder text */
|
| + color: green;
|
| + }
|
| + paper-input-decorator /deep/ ::-moz-placeholder {
|
| + color: green;
|
| + }
|
| + paper-input-decorator /deep/ :-ms-input-placeholder {
|
| + color: green;
|
| + }
|
| +
|
| + paper-input-decorator /deep/ .unfocused-underline {
|
| + /* line color when the input is unfocused */
|
| + background-color: green;
|
| + }
|
| +
|
| + paper-input-decorator[focused] /deep/ .floating-label .label-text {
|
| + /* floating label color when the input is focused */
|
| + color: orange;
|
| + }
|
| +
|
| + paper-input-decorator /deep/ .focused-underline {
|
| + /* line color when the input is focused */
|
| + background-color: orange;
|
| + }
|
| +
|
| + paper-input-decorator.invalid[focused] /deep/ .floated-label .label-text,
|
| + paper-input-decorator[focused] /deep/ .error {
|
| + /* floating label, error message nad error icon color when the input is invalid and focused */
|
| + color: salmon;
|
| + }
|
| +
|
| + paper-input-decorator.invalid /deep/ .focused-underline {
|
| + /* line and color when the input is invalid and focused */
|
| + background-color: salmon;
|
| + }
|
| +
|
| +Form submission
|
| +---------------
|
| +
|
| +You can use inputs decorated with this element in a `form` as usual.
|
| +
|
| +Validation
|
| +----------
|
| +
|
| +Because you provide the `input` element to `paper-input-decorator`, you can use any validation library
|
| +or the <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation">HTML5 Constraints Validation API</a>
|
| +to implement validation. Set the `isInvalid` attribute when the input is validated, and provide an
|
| +error message in the `error` attribute.
|
| +
|
| +Example:
|
| +
|
| + <paper-input-decorator id="paper1" error="Value must start with a number!">
|
| + <input id="input1" is="core-input" pattern="^[0-9].*">
|
| + </paper-input-decorator>
|
| + <button onclick="validate()"></button>
|
| + <script>
|
| + function validate() {
|
| + var decorator = document.getElementById('paper1');
|
| + var input = document.getElementById('input1');
|
| + decorator.isInvalid = !input.validity.valid;
|
| + }
|
| + </script>
|
| +
|
| +Example to validate as the user types:
|
| +
|
| + <template is="auto-binding">
|
| + <paper-input-decorator id="paper2" error="Value must start with a number!" isInvalid="{{!$.input2.validity.valid}}">
|
| + <input id="input2" is="core-input" pattern="^[0-9].*">
|
| + </paper-input-decorator>
|
| + </template>
|
| +
|
| +Accessibility
|
| +-------------
|
| +
|
| +`paper-input-decorator` will automatically set the `aria-label` attribute on the nested input
|
| +to the value of `label`. Do not set the `placeholder` attribute on the nested input, as it will
|
| +conflict with this element.
|
| +
|
| +@group Paper Elements
|
| +@element paper-input-decorator
|
| +@homepage github.io
|
| +-->
|
| +<link href="../polymer/polymer.html" rel="import">
|
| +<link href="../core-icon/core-icon.html" rel="import">
|
| +<link href="../core-icons/core-icons.html" rel="import">
|
| +<link href="../core-input/core-input.html" rel="import">
|
| +<link href="../core-style/core-style.html" rel="import">
|
| +
|
| +<core-style id="paper-input-decorator">
|
| +
|
| +.label-text,
|
| +.error {
|
| + color: {{g.paperInput.labelColor}};
|
| +}
|
| +
|
| +::-webkit-input-placeholder {
|
| + color: {{g.paperInput.labelColor}};
|
| +}
|
| +
|
| +::-moz-placeholder {
|
| + color: {{g.paperInput.labelColor}};
|
| +}
|
| +
|
| +:-ms-input-placeholder {
|
| + color: {{g.paperInput.labelColor}};
|
| +}
|
| +
|
| +.unfocused-underline {
|
| + background-color: {{g.paperInput.labelColor}};
|
| +}
|
| +
|
| +:host([focused]) .floated-label .label-text {
|
| + color: {{g.paperInput.focusedColor}};
|
| +}
|
| +
|
| +.focused-underline {
|
| + background-color: {{g.paperInput.focusedColor}};
|
| +}
|
| +
|
| +:host(.invalid) .floated-label .label-text,
|
| +.error {
|
| + color: {{g.paperInput.invalidColor}};
|
| +}
|
| +
|
| +:host(.invalid) .unfocused-underline,
|
| +:host(.invalid) .focused-underline {
|
| + background-color: {{g.paperInput.invalidColor}};
|
| +}
|
| +
|
| +</core-style>
|
| +
|
| +<polymer-element name="paper-input-decorator" layout vertical
|
| + on-transitionEnd="{{transitionEndAction}}" on-webkitTransitionEnd="{{transitionEndAction}}"
|
| + on-input="{{inputAction}}"
|
| + on-down="{{downAction}}">
|
| +
|
| + <template>
|
| +
|
| + <link href="paper-input-decorator.css" rel="stylesheet">
|
| + <core-style ref="paper-input-decorator"></core-style>
|
| +
|
| + <div class="floated-label" aria-hidden="true" hidden?="{{!floatingLabel}}" invisible?="{{!floatingLabelVisible || labelAnimated}}">
|
| + <!-- needed for floating label animation measurement -->
|
| + <span id="floatedLabelText" class="label-text">{{label}}</span>
|
| + </div>
|
| +
|
| + <div class="input-body" flex auto relative>
|
| +
|
| + <div class="label" fit invisible aria-hidden="true">
|
| + <!-- needed for floating label animation measurement -->
|
| + <span id="labelText" class="label-text" invisible?="{{!_labelVisible}}" animated?="{{labelAnimated}}">{{label}}</span>
|
| + </div>
|
| +
|
| + <content></content>
|
| +
|
| + </div>
|
| +
|
| + <div id="underline" class="underline" relative>
|
| + <div class="unfocused-underline" fit invisible?="{{disabled}}"></div>
|
| + <div id="focusedUnderline" class="focused-underline" fit invisible?="{{!focused}}" animated?="{{underlineAnimated}}"></div>
|
| + </div>
|
| +
|
| + <div class="error" layout horizontal center hidden?="{{!isInvalid}}">
|
| + <div class="error-text" flex auto role="alert" aria-hidden="{{!isInvalid}}">{{error}}</div>
|
| + <core-icon class="error-icon" icon="warning"></core-icon>
|
| + </div>
|
| +
|
| + </template>
|
| +
|
| + <script>
|
| +
|
| + (function() {
|
| +
|
| + var paperInput = CoreStyle.g.paperInput = CoreStyle.g.paperInput || {};
|
| +
|
| + paperInput.labelColor = '#757575';
|
| + paperInput.focusedColor = '#4059a9';
|
| + paperInput.invalidColor = '#d34336';
|
| +
|
| + Polymer({
|
| +
|
| + publish: {
|
| +
|
| + /**
|
| + * The label for this input. It normally appears as grey text inside
|
| + * the text input and disappears once the user enters text.
|
| + *
|
| + * @attribute label
|
| + * @type string
|
| + * @default ''
|
| + */
|
| + label: '',
|
| +
|
| + /**
|
| + * If true, the label will "float" above the text input once the
|
| + * user enters text instead of disappearing.
|
| + *
|
| + * @attribute floatingLabel
|
| + * @type boolean
|
| + * @default false
|
| + */
|
| + floatingLabel: false,
|
| +
|
| + /**
|
| + * Set to true to style the element as disabled.
|
| + *
|
| + * @attribute disabled
|
| + * @type boolean
|
| + * @default false
|
| + */
|
| + disabled: {value: false, reflect: true},
|
| +
|
| + /**
|
| + * Use this property to override the automatic label visibility.
|
| + * If this property is set to `true` or `false`, the label visibility
|
| + * will respect this value instead of be based on whether there is
|
| + * a non-null value in the input.
|
| + *
|
| + * @attribute labelVisible
|
| + * @type boolean
|
| + * @default false
|
| + */
|
| + labelVisible: null,
|
| +
|
| + /**
|
| + * Set this property to true to show the error message.
|
| + *
|
| + * @attribute isInvalid
|
| + * @type boolean
|
| + * @default false
|
| + */
|
| + isInvalid: false,
|
| +
|
| + /**
|
| + * The message to display if the input value fails validation. If this
|
| + * is unset or the empty string, a default message is displayed depending
|
| + * on the type of validation error.
|
| + *
|
| + * @attribute error
|
| + * @type string
|
| + */
|
| + error: '',
|
| +
|
| + focused: {value: false, reflect: true}
|
| +
|
| + },
|
| +
|
| + computed: {
|
| + floatingLabelVisible: 'floatingLabel && !_labelVisible',
|
| + _labelVisible: '(labelVisible === true || labelVisible === false) ? labelVisible : _autoLabelVisible'
|
| + },
|
| +
|
| + ready: function() {
|
| + // Delegate focus/blur events
|
| + Polymer.addEventListener(this, 'focus', this.focusAction.bind(this), true);
|
| + Polymer.addEventListener(this, 'blur', this.blurAction.bind(this), true);
|
| + },
|
| +
|
| + attached: function() {
|
| + this.input = this.querySelector('input,textarea');
|
| +
|
| + this.mo = new MutationObserver(function() {
|
| + this.input = this.querySelector('input,textarea');
|
| + }.bind(this));
|
| + this.mo.observe(this, {childList: true});
|
| + },
|
| +
|
| + detached: function() {
|
| + this.mo.disconnect();
|
| + this.mo = null;
|
| + },
|
| +
|
| + prepareLabelTransform: function() {
|
| + var toRect = this.$.floatedLabelText.getBoundingClientRect();
|
| + var fromRect = this.$.labelText.getBoundingClientRect();
|
| + if (toRect.width !== 0) {
|
| + var sy = toRect.height / fromRect.height;
|
| + this.$.labelText.cachedTransform =
|
| + 'scale3d(' + (toRect.width / fromRect.width) + ',' + sy + ',1) ' +
|
| + 'translate3d(0,' + (toRect.top - fromRect.top) / sy + 'px,0)';
|
| + }
|
| + },
|
| +
|
| + animateFloatingLabel: function() {
|
| + if (!this.floatingLabel || this.labelAnimated) {
|
| + return false;
|
| + }
|
| +
|
| + if (!this.$.labelText.cachedTransform) {
|
| + this.prepareLabelTransform();
|
| + }
|
| +
|
| + // If there's still no cached transform, the input is invisible so don't
|
| + // do the animation.
|
| + if (!this.$.labelText.cachedTransform) {
|
| + return false;
|
| + }
|
| +
|
| + this.labelAnimated = true;
|
| + // Handle interrupted animation
|
| + this.async(function() {
|
| + this.transitionEndAction();
|
| + }, null, 250);
|
| +
|
| + if (this._labelVisible) {
|
| + // Handle if the label started out floating
|
| + if (!this.$.labelText.style.webkitTransform && !this.$.labelText.style.transform) {
|
| + this.$.labelText.style.webkitTransform = this.$.labelText.cachedTransform;
|
| + this.$.labelText.style.transform = this.$.labelText.cachedTransform;
|
| + this.$.labelText.offsetTop;
|
| + }
|
| + this.$.labelText.style.webkitTransform = '';
|
| + this.$.labelText.style.transform = '';
|
| + } else {
|
| + this.$.labelText.style.webkitTransform = this.$.labelText.cachedTransform;
|
| + this.$.labelText.style.transform = this.$.labelText.cachedTransform;
|
| + this.input.placeholder = '';
|
| + }
|
| +
|
| + return true;
|
| + },
|
| +
|
| + _labelVisibleChanged: function(old) {
|
| + // do not do the animation on first render
|
| + if (old !== undefined) {
|
| + if (!this.animateFloatingLabel()) {
|
| + this.updateInputLabel(this.input, this.label);
|
| + }
|
| + }
|
| + },
|
| +
|
| + labelVisibleChanged: function() {
|
| + if (this.labelVisible === 'true') {
|
| + this.labelVisible = true;
|
| + } else if (this.labelVisible === 'false') {
|
| + this.labelVisible = false;
|
| + }
|
| + },
|
| +
|
| + labelChanged: function() {
|
| + if (this.input) {
|
| + this.updateInputLabel(this.input, this.label);
|
| + }
|
| + },
|
| +
|
| + isInvalidChanged: function() {
|
| + this.classList.toggle('invalid', this.isInvalid);
|
| + },
|
| +
|
| + focusedChanged: function() {
|
| + this.updateLabelVisibility(this.input && this.input.value);
|
| + },
|
| +
|
| + inputChanged: function(old) {
|
| + if (this.input) {
|
| + this.updateLabelVisibility(this.input.value);
|
| + this.updateInputLabel(this.input, this.label);
|
| + }
|
| + if (old) {
|
| + this.updateInputLabel(old, '');
|
| + }
|
| + },
|
| +
|
| + focusAction: function() {
|
| + this.focused = true;
|
| + },
|
| +
|
| + blurAction: function(e) {
|
| + this.focused = false;
|
| + },
|
| +
|
| + /**
|
| + * Updates the label visibility based on a value. This is handled automatically
|
| + * if the user is typing, but if you imperatively set the input value you need
|
| + * to call this function.
|
| + *
|
| + * @method updateLabelVisibility
|
| + * @param {string} value
|
| + */
|
| + updateLabelVisibility: function(value) {
|
| + var v = (value !== null && value !== undefined) ? String(value) : value;
|
| + this._autoLabelVisible = (!this.focused && !v) || (!this.floatingLabel && !v);
|
| + },
|
| +
|
| + updateInputLabel: function(input, label) {
|
| + if (this._labelVisible) {
|
| + this.input.placeholder = this.label;
|
| + } else {
|
| + this.input.placeholder = '';
|
| + }
|
| + if (label) {
|
| + input.setAttribute('aria-label', label);
|
| + } else {
|
| + input.removeAttribute('aria-label');
|
| + }
|
| + },
|
| +
|
| + inputAction: function(e) {
|
| + this.updateLabelVisibility(e.target.value);
|
| + },
|
| +
|
| + downAction: function(e) {
|
| + if (this.disabled) {
|
| + return;
|
| + }
|
| +
|
| + if (this.focused) {
|
| + return;
|
| + }
|
| +
|
| + if (this.input) {
|
| + this.input.focus();
|
| + e.preventDefault();
|
| + }
|
| +
|
| + // The underline spills from the tap location
|
| + var rect = this.$.underline.getBoundingClientRect();
|
| + var right = e.x - rect.left;
|
| + this.$.focusedUnderline.style.mozTransformOrigin = right + 'px';
|
| + this.$.focusedUnderline.style.webkitTransformOrigin = right + 'px ';
|
| + this.$.focusedUnderline.style.transformOriginX = right + 'px';
|
| +
|
| + // Animations only run when the user interacts with the input
|
| + this.underlineAnimated = true;
|
| +
|
| + // Handle interrupted animation
|
| + this.async(function() {
|
| + this.transitionEndAction();
|
| + }, null, 250);
|
| + },
|
| +
|
| + transitionEndAction: function() {
|
| + this.underlineAnimated = false;
|
| + this.labelAnimated = false;
|
| + if (this._labelVisible) {
|
| + this.input.placeholder = this.label;
|
| + }
|
| + }
|
| +
|
| + });
|
| +
|
| + }());
|
| +
|
| + </script>
|
| +
|
| +</polymer-element>
|
|
|