api-console-assets
Version:
This repo only exists to publish api console components to npm
247 lines (216 loc) • 7.18 kB
HTML
<!--
@license
Copyright 2017 Mulesoft.
All rights reserved.
-->
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-a11y-announcer/iron-a11y-announcer.html">
<link rel="import" href="../iron-form-element-behavior/iron-form-element-behavior.html">
<link rel="import" href="../iron-validatable-behavior/iron-validatable-behavior.html">
<link rel="import" href="paper-input-container.html">
<link rel="import" href="paper-input-behavior.html">
<link rel="import" href="paper-input-error.html">
<!--
`<paper-textarea>` is a multi line text input styled for the Anypoint platform
as a Polymer powered web component
### Example
```
<paper-textarea></paper-textarea>
```
### Styling
See `paper-input-container` for styling options.
@demo demo/index.html
-->
<dom-module id="paper-textarea">
<template>
<style>
:host {
display: block;
}
:host {
display: block;
}
:host([hidden]) {
display: none ;
}
label {
pointer-events: none;
}
paper-input-error {
-webkit-transform-origin: center center;
transform-origin: center center;
-webkit-transition: all .2s ease-out;
transition: all .2s ease-out;
}
:host(:not([focused])) paper-input-error {
transform: translate(2px);
}
</style>
<paper-input-container
no-label-float="[[noLabelFloat]]"
auto-validate$="[[autoValidate]]"
disabled$="[[disabled]]"
invalid="[[invalid]]"
always-float-label="[[_computeAlwaysFloatLabel(alwaysFloatLabel,placeholder)]]">
<label hidden$="[[!label]]" aria-hidden="true" for$="[[_inputId]]">[[label]]</label>
<textarea
id$="[[_inputId]]"
value="{{value::input}}"
disabled$="[[disabled]]"
title$="[[title]]"
required$="[[required]]"
autocomplete$="[[autocomplete]]"
autofocus$="[[autofocus]]"
inputmode$="[[inputmode]]"
minlength$="[[minlength]]"
maxlength$="[[maxlength]]"
name$="[[name]]"
placeholder$="[[placeholder]]"
readonly$="[[readonly]]"
autocapitalize$="[[autocapitalize]]"
rows$="[[rows]]"></textarea>
<template is="dom-if" if="[[hasValidationMessage]]">
<paper-input-error aria-live="assertive" error-message="[[errorMessage]]" invalid="[[invalid]]" focused="[[focused]]" horizontal-align="right"></paper-input-error>
</template>
</paper-input-container>
</template>
<script>
Polymer({
is: 'paper-textarea',
behaviors: [
Polymer.IronFormElementBehavior,
Polymer.PaperInputBehavior,
Polymer.IronValidatableBehavior
],
properties: {
_ariaLabelledBy: {
observer: '_ariaLabelledByChanged',
type: String
},
_ariaDescribedBy: {
observer: '_ariaDescribedByChanged',
type: String
},
/**
* The initial number of rows.
*
* @type number
*/
rows: {
type: Number,
value: 3
},
_patternAlreadyChecked: {
type: Boolean,
value: false
},
value: {
type: String,
notifyL: true
}
},
listeners: {
'input': '_onInput',
'keypress': '_onKeypress'
},
_ariaLabelledByChanged: function(ariaLabelledBy) {
this.inputElement.setAttribute('aria-labelledby', ariaLabelledBy);
},
_ariaDescribedByChanged: function(ariaDescribedBy) {
this.inputElement.setAttribute('aria-describedby', ariaDescribedBy);
},
get _focusableElement() {
return this.inputElement;
},
get _patternRegExp() {
var pattern;
if (this.allowedPattern) {
pattern = new RegExp(this.allowedPattern);
} else {
switch (this.type) {
case 'number':
pattern = /[0-9.,e-]/;
break;
}
}
return pattern;
},
_onInput: function() {
// Need to validate each of the characters pasted if they haven't
// been validated inside `_onKeypress` already.
if (this.preventInvalidInput && !this._patternAlreadyChecked) {
var valid = this._checkPatternValidity();
if (!valid) {
this._announceInvalidCharacter('Invalid string of characters not entered.');
this.value = this._previousValidInput;
}
}
this._previousValidInput = this.value;
this._patternAlreadyChecked = false;
},
_checkPatternValidity: function() {
var regexp = this._patternRegExp;
if (!regexp) {
return true;
}
for (var i = 0; i < this.value.length; i++) {
if (!regexp.test(this.value[i])) {
return false;
}
}
return true;
},
_announceInvalidCharacter: function(message) {
this.fire('iron-announce', {text: message});
},
_onKeypress: function(event) {
if (!this.preventInvalidInput && this.type !== 'number') {
return;
}
var regexp = this._patternRegExp;
if (!regexp) {
return;
}
// Handle special keys and backspace
if (event.metaKey || event.ctrlKey || event.altKey) {
return;
}
// Check the pattern either here or in `_onInput`, but not in both.
this._patternAlreadyChecked = true;
var thisChar = String.fromCharCode(event.charCode);
if (this._isPrintable(event) && !regexp.test(thisChar)) {
event.preventDefault();
this._announceInvalidCharacter('Invalid character ' + thisChar + ' not entered.');
}
},
_isPrintable: function(event) {
// What a control/printable character is varies wildly based on the browser.
// - most control characters (arrows, backspace) do not send a `keypress` event
// in Chrome, but the *do* on Firefox
// - in Firefox, when they do send a `keypress` event, control chars have
// a charCode = 0, keyCode = xx (for ex. 40 for down arrow)
// - printable characters always send a keypress event.
// - in Firefox, printable chars always have a keyCode = 0. In Chrome, the keyCode
// always matches the charCode.
// None of this makes any sense.
// For these keys, ASCII code == browser keycode.
var anyNonPrintable =
(event.keyCode === 8) || // backspace
(event.keyCode === 9) || // tab
(event.keyCode === 13) || // enter
(event.keyCode === 27); // escape
// For these keys, make sure it's a browser keycode and not an ASCII code.
var mozNonPrintable =
(event.keyCode === 19) || // pause
(event.keyCode === 20) || // caps lock
(event.keyCode === 45) || // insert
(event.keyCode === 46) || // delete
(event.keyCode === 144) || // num lock
(event.keyCode === 145) || // scroll lock
(event.keyCode > 32 && event.keyCode < 41) || // page up/down, end, home, arrows
(event.keyCode > 111 && event.keyCode < 124); // fn keys
return !anyNonPrintable && !(event.charCode === 0 && mozNonPrintable);
}
});
</script>
</dom-module>