1<!-- 2Copyright (c) 2014 The Polymer Project Authors. All rights reserved. 3This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE 4The complete set of authors may be found at http://polymer.github.io/AUTHORS 5The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS 6Code distributed by Google as part of the polymer project is also 7subject to an additional IP rights grant found at http://polymer.github.io/PATENTS 8--> 9 10<!-- 11`paper-autogrow-textarea` is an element containing a textarea that grows in height as more 12lines of input are entered. Unless an explicit height or the `maxRows` property is set, it will 13never scroll. 14 15Example: 16 17 <paper-autogrow-textarea id="a1"> 18 <textarea id="t1"></textarea> 19 </paper-autogrow-textarea> 20 21Because the `textarea`'s `value` property is not observable, if you set the `value` imperatively 22you must call `update` to notify this element the value has changed. 23 24Example: 25 26 /* using example HTML above */ 27 t1.value = 'some\ntext'; 28 a1.update(); 29 30@group Paper Elements 31@element paper-autogrow-textarea 32@status unstable 33--> 34 35<link href="../polymer/polymer.html" rel="import"> 36 37<polymer-element name="paper-autogrow-textarea" on-input="{{inputAction}}"> 38<template> 39 40 <style> 41 :host { 42 display: inline-block; 43 position: relative; 44 width: 400px; 45 } 46 47 .mirror-text { 48 visibility: hidden; 49 word-wrap: break-word; 50 } 51 52 ::content textarea { 53 padding: 0; 54 margin: 0; 55 border: none; 56 outline: none; 57 resize: none; 58 /* see comments in template */ 59 width: 100%; 60 height: 100%; 61 } 62 63 ::content textarea:invalid { 64 box-shadow: none; 65 } 66 </style> 67 68 <!-- the mirror sizes the input/textarea so it grows with typing --> 69 <div id="mirror" class="mirror-text" aria-hidden="true"> </div> 70 71 <!-- size the input/textarea with a div, because the textarea has intrinsic size in ff --> 72 <div class="textarea-container" fit> 73 <content></content> 74 </div> 75 76</template> 77<script> 78 79 Polymer({ 80 81 publish: { 82 83 /** 84 * The textarea that should auto grow. 85 * 86 * @attribute target 87 * @type HTMLTextAreaElement 88 * @default null 89 */ 90 target: null, 91 92 /** 93 * The initial number of rows. 94 * 95 * @attribute rows 96 * @type number 97 * @default 1 98 */ 99 rows: 1, 100 101 /** 102 * The maximum number of rows this element can grow to until it 103 * scrolls. 0 means no maximum. 104 * 105 * @attribute maxRows 106 * @type number 107 * @default 0 108 */ 109 maxRows: 0 110 }, 111 112 tokens: null, 113 114 observe: { 115 rows: 'updateCached', 116 maxRows: 'updateCached' 117 }, 118 119 constrain: function(tokens) { 120 var _tokens; 121 tokens = tokens || ['']; 122 // Enforce the min and max heights for a multiline input to avoid measurement 123 if (this.maxRows > 0 && tokens.length > this.maxRows) { 124 _tokens = tokens.slice(0, this.maxRows); 125 } else { 126 _tokens = tokens.slice(0); 127 } 128 while (this.rows > 0 && _tokens.length < this.rows) { 129 _tokens.push(''); 130 } 131 return _tokens.join('<br>') + ' '; 132 }, 133 134 valueForMirror: function(input) { 135 this.tokens = (input && input.value) ? input.value.replace(/&/gm, '&').replace(/"/gm, '"').replace(/'/gm, ''').replace(/</gm, '<').replace(/>/gm, '>').split('\n') : ['']; 136 return this.constrain(this.tokens); 137 }, 138 139 /** 140 * Sizes this element to fit the input value. This function is automatically called 141 * when the user types in new input, but you must call this function if the value 142 * is updated imperatively. 143 * 144 * @method update 145 * @param Element The input 146 */ 147 update: function(input) { 148 this.$.mirror.innerHTML = this.valueForMirror(input); 149 }, 150 151 updateCached: function() { 152 this.$.mirror.innerHTML = this.constrain(this.tokens); 153 }, 154 155 inputAction: function(e) { 156 this.update(e.target); 157 } 158 159 }); 160 161</script> 162</polymer-element> 163